您的位置 首页 java

Hibernate实体关系映射

上一篇文章我们学习了 Hibernate 的框架搭建,并且完成了单表的 CRUD 操作,今天我们来学习 Hibernate 中的多表关联。

主要来说最常见的两种关系: 一对多关系,多对多关系

我们写程序就是为了解决现实生活中的问题,所以我们用现实生活中的例子去理解程序就会比较容易。

一对多关系:

生活中常见的一对多关系就是客户和订单的关系, 每一个客户可以购买多个产品,生成多个订单,但是一个订单只能属于一个客户,所以客户(Customer)是一,订单(Orders)是多

这种关系在数据库中如何体现呢?

数据表中一的一方是主表(Customer),多的一方是从表(Orders),通过主 外键 关联关系来维护这种关系。

从表中的 cid 为外键,该外键被主表的 主键 id 所约束

在面向对象的思想中,如何体现这一关系呢?

在面向对象的场景中它们的关系应该是 Orders 拥有一个 Customer 对象属性,Customer 拥有一个 Orders 集合属性

public class Customer {
 private int id;
 private String name;
 private Set<Orders> orders;
 public int getId() {
 return id;
 }
 public void setId(int id) {
 this.id = id;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public Set<Orders> getOrders() {
 return orders;
 }
 public void setOrders(Set<Orders> orders) {
 this.orders = orders;
 }
}
 
public class Orders {
 private int id;
 private String name;
 private Customer customer;
 public int getId() {
 return id;
 }
 public void setId(int id) {
 this.id = id;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public Customer getCustomer() {
 return customer;
 }
 public void setCustomer(Customer customer) {
 this.customer = customer;
 }
}
 

多对多关系:

大学生选课则是一个典型的多对多关系的体现,我们知道一个学生可以选择多门课程,同时,一门课程也可以被多个学生选择,所以 学生(Student)是多,课程(Classes)也是多

数据库中是通过两个一对多关系来维护这种关系的,即 Student 表和 Classes 都是主表,额外增加一张中间表作为从表(Student_Classes) 两张主表与中间表之间都是一对多的关系

中间表(Student_Classes)中的 sid 和 cid 均为外键,分别被 Student 表的 id 和 Classes 表的 id 约束。

在面向对象的场景中它 们的关系应该是 Student 拥有一个 Classes 集合属性,同时,Classes 拥有一个 Student 集合属性

public class Student {
 private int id;
 private String name;
 private Set<Classes> classes;
 public int getId() {
 return id;
 }
 public void setId(int id) {
 this.id = id;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public Set<Classes> getClasses() {
 return classes;
 }
 public void setClasses(Set<Classes> classes) {
 this.classes = classes;
 }
}
 
public class Classes {
 private int id;
 private String name;
 private Set<Student> students;
 public int getId() {
 return id;
 }
 public void setId(int id) {
 this.id = id;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public Set<Student> getStudents() {
 return students;
 }
 public void setStudents(Set<Student> students) {
 this.students = students;
 }
}
 

好了,解释完一对多和多对多关系,我们会发现 Java 与数据库完全是两种思维方式来体现这两个关系,Hibernate 框架的作用就是将这两种思维方式进行转换和映射。

通过前面的学习,我们知道 Hibernate 框架是通过配置实体关系映射文件进行转换的。

一对多

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"">
<hibernate-mapping package="com.southwind.entity">
 <class name="Customer" table="customer">
 <!-- 配置主键映射 -->
 <id name="id" type="java.lang.Integer">
 <column name="id"></column>
 <!-- 设置主键生成方式 -->
 <generator class="native"></generator>
 </id>
 <!-- 配置其他属性 -->
 <property name="name" type="java.lang.String">
 <column name="name"></column>
 </property>
 <set name="orders" table="orders" lazy="extra">
 <!-- 配置外键 -->
 <key column="cid"></key>
 <one-to-many class="Orders"/>
 </set>
 </class>
</hibernate-mapping>
 

Customer.hbm.xml:

set标签来配置实体类中的集合属性orders;

name与实体类属性名对应;

table与数据表字段名对应;

key与外键字段名对应;

one-to-many与集合泛型的实体类对应。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"">
<hibernate-mapping package="com.southwind.entity">
 <class name="Orders" table="orders">
 <!-- 配置主键映射 -->
 <id name="id" type="java.lang.Integer">
 <column name="id"></column>
 <!-- 设置主键生成方式 -->
 <generator class="native"></generator>
 </id>
 <!-- 配置其他属性 -->
 <property name="name" type="java.lang.String">
 <column name="name"></column>
 </property>
 <many-to-one name="customer" class="Customer" column="cid"></many-to-one>
 </class>
</hibernate-mapping>
 

Orders.hbm.xml :

many-to-one标签来配置实体类对应的对象属性customer;

name与属性名对应;

class与属性的所属类对应;

column与外键字段名对应。

同时,不要忘记将这两个配置文件添加到 hibernate.cfg.xml 中。

 <!-- 添加实体关系映射文件 -->
 <mapping resource="com/southwind/entity/Customer.hbm.xml"/>
 <mapping resource="com/southwind/entity/Orders.hbm.xml"/>
 

接下来就可以调用 Hibernate API 进行操作了。

public class Test {
 public static void main(String[] args) {
 //1.创建 configuration 对象,加载hibernate.cfg.xml
 Configuration configuration = new Configuration();
 configuration = configuration.configure();
 //2.创建ServiceRegistry对象,hibernate.cfg.xml所有配置需要在该对象中进行注册才能生效
 ServiceRegistryBuilder srb = new ServiceRegistryBuilder();
 srb.applySettings(configuration.getProperties());
 ServiceRegistry sr = srb.buildServiceRegistry();
 //3.创建SessionFactory对象
 SessionFactory sessionFactory = configuration.buildSessionFactory(sr);
 //4.创建Session对象
 Session session = sessionFactory.openSession();
 //5.创建Customer对象
 Customer customer = new Customer();
 customer.setName("张三");
 //6.创建Orders对象
 Orders orders = new Orders();
 orders.setName("订单1");
 //7.建立关联关系
 orders.setCustomer(customer);
 //8.保存
 session.save(customer);
 session.save(orders);
 //9.提交事务
 session.beginTransaction().commit();
 //10.关闭session
 session.close();
 }
}
 

多对多:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"">
<hibernate-mapping package="com.southwind.entity">
 <class name="Classes" table="classes">
 <!-- 配置主键映射 -->
 <id name="id" type="java.lang.Integer">
 <column name="id"></column>
 <!-- 设置主键生成方式 -->
 <generator class="native"></generator>
 </id>
 <!-- 配置其他属性 -->
 <property name="name" type="java.lang.String">
 <column name="name"></column>
 </property>
 <set name="students" table="students_classes">
 <!-- 配置外键 -->
 <key column="cid"></key>
 <many-to-many class="Student" column="sid"></many-to-many>
 </set>
 </class>
</hibernate-mapping>
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"">
<hibernate-mapping package="com.southwind.entity">
 <class name="Student" table="student">
 <!-- 配置主键映射 -->
 <id name="id" type="java.lang.Integer">
 <column name="id"></column>
 <!-- 设置主键生成方式 -->
 <generator class="native"></generator>
 </id>
 <!-- 配置其他属性 -->
 <property name="name" type="java.lang.String">
 <column name="name"></column>
 </property>
 <set name="classes" table="students_classes">
 <!-- 配置外键 -->
 <key column="sid"></key>
 <many-to-many class="Classes" column="cid"></many-to-many>
 </set>
 </class>
</hibernate-mapping>
 

Classes.hbm.xml 和 Student.hbm.xml 中都是通过 set 标签来配置双向关系的 :

name是实体类对应的集合属性名,

table对应中间表名,

key对应中间表的外键字段名,

many-to-many与集合泛型的实体类对应,column属性与中间表的外键字段名对应。

将这两个配置文件添加到 hibernate.cfg.xml 中。

 <!-- 添加实体关系映射文件 -->
 <mapping resource="com/southwind/entity/Customer.hbm.xml"/>
 <mapping resource="com/southwind/entity/Orders.hbm.xml"/>
 <mapping resource="com/southwind/entity/Classes.hbm.xml"/>
 <mapping resource="com/southwind/entity/Student.hbm.xml"/>
 

调用 Hibernate API 进行操作。

public class Test {
 public static void main(String[] args) {
 //1.创建Configuration对象,加载hibernate.cfg.xml
 Configuration configuration = new Configuration();
 configuration = configuration.configure();
 
 //2.创建ServiceRegistry对象,hibernate.cfg.xml所有配置需要在该对象中进行注册才能生效
 ServiceRegistryBuilder srb = new ServiceRegistryBuilder();
 srb.applySettings(configuration.getProperties());
 ServiceRegistry sr = srb.buildServiceRegistry();
 
 //3.创建SessionFactory对象
 SessionFactory sessionFactory = configuration.buildSessionFactory(sr);
 
 //4.创建Session对象
 Session session = sessionFactory.openSession();
 //5.创建Classes对象
 Classes classes = new Classes();
 classes.setName("Java");
 //6.创建Student对象
 Student student = new Student();
 student.setName("张三");
 //7.建立关联关系
 Set<Classes> classesSet = new HashSet<Classes>();
 classesSet.add(classes);
 student.setClasses(classesSet);
 //8.保存
 session.save(classes);
 session.save(student);
 //9.提交事务
 session.beginTransaction().commit();
 //10.关闭session
 session.close();
 }
}
 

总结:

使用 Hibernate 完成一对多和多对多关系映射,重点是要理解两点:

1、数据表中如何维护;

2、Java代码中如何维护。

搞清楚这两者的区别,就明白了 Hibernate 框架的用法,使用 Hibernate 特定的标签进行配置即可。

关注微信公众号「Java大联盟」,关注即可获取海量学习干货,同时还有不定期送书,键盘,鼠标等粉丝福利。

Hibernate实体关系映射

赶快来关注一波,海量资源拿到手软。

文章来源:智云一二三科技

文章标题:Hibernate实体关系映射

文章地址:https://www.zhihuclub.com/177164.shtml

关于作者: 智云科技

热门文章

网站地图