Hibernate的多对一映射

一、创建Java工程,新建Lib文件夹,加入Hibernate和数据库(如MySql、Oracle、SqlServer等)的Jar包,创建 hibernate.cfg.xml 文件,并配置,配置项如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6     <session-factory>
 7     
 8         <!-- 配置连接数据库的基本信息 -->
 9         <property name="connection.username">root</property>
10         <property name="connection.password"></property>
11         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
12         <!-- <property name="connection.url">jdbc:mysql:///mis</property> -->
13         <property name="connection.url">
14             <!-- 解决Mysql插入中文乱码的问题 -->
15             <![CDATA[jdbc:mysql://localhost:3306/mis?useUnicode=true&characterEncoding=utf8]]>
16         </property>
17 
18 
19         <!-- 配置 hibernate 的基本信息 -->
20         <!-- hibernate 所使用的数据库方言 -->
21         <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
22 
23         <!-- 执行操作时是否在控制台打印 SQL -->
24         <property name="show_sql">true</property>
25 
26         <!-- 是否对 SQL 进行格式化 -->
27         <property name="format_sql">true</property>
28 
29         <!-- 指定自动生成数据表的策略 -->
30         <property name="hbm2ddl.auto">update</property>
31         
32         <!-- 设置 Hibernate 的事务隔离级别 2:读已提交的记录-->
33         <property name="connection.isolation">2</property>
34         
35         <!-- 删除对象后, 使其 OID 置为 null -->
36         <property name="use_identifier_rollback">true</property>
37         
38         <!-- 配置 C3P0 数据源 -->
39         <property name="hibernate.c3p0.max_size">10</property>
40         <property name="hibernate.c3p0.min_size">5</property>
41         <property name="c3p0.acquire_increment">2</property>
42         
43         <property name="c3p0.idle_test_period">2000</property>
44         <property name="c3p0.timeout">2000</property>
45         
46         <property name="c3p0.max_statements">10</property>
47         
48         <!-- 设定 JDBC 的 Statement 读取数据的时候每次从数据库中取出的记录条数 -->
49         <property name="hibernate.jdbc.fetch_size">100</property>
50         
51         <!-- 设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小 -->
52         <property name="jdbc.batch_size">30</property>
53 
54         <!-- 指定关联的 .hbm.xml 文件 -->
55         <!-- 
56         <mapping resource="com/mcs/hibernate/entities/News.hbm.xml" />
57         <mapping resource="com/mcs/hibernate/entities/Worker.hbm.xml" />
58         
59         <mapping resource="com/mcs/hibernate/entities/n21/Customer.hbm.xml" />
60         <mapping resource="com/mcs/hibernate/entities/n21/Order.hbm.xml" />
61          -->
62          
63         <mapping resource="com/mcs/hibernate/entities/n21/both/Customer.hbm.xml" />
64         <mapping resource="com/mcs/hibernate/entities/n21/both/Order.hbm.xml" />
65 
66     </session-factory>
67 
68 </hibernate-configuration>
View Code

二、单向的多对一映射

1、创建Java实体类

 1 package com.mcs.hibernate.entities.n21;
 2 
 3 public class Customer {
 4 
 5     private Integer customerId;
 6     private String customerName;
 7 
 8     public Integer getCustomerId() {
 9         return customerId;
10     }
11 
12     public void setCustomerId(Integer customerId) {
13         this.customerId = customerId;
14     }
15 
16     public String getCustomerName() {
17         return customerName;
18     }
19 
20     public void setCustomerName(String customerName) {
21         this.customerName = customerName;
22     }
23 
24 }
View Code
 1 package com.mcs.hibernate.entities.n21;
 2 
 3 public class Order {
 4     
 5     private Integer orderId;
 6     private String orderName;
 7     
 8     private Customer customer;
 9 
10     public Integer getOrderId() {
11         return orderId;
12     }
13 
14     public void setOrderId(Integer orderId) {
15         this.orderId = orderId;
16     }
17 
18     public String getOrderName() {
19         return orderName;
20     }
21 
22     public void setOrderName(String orderName) {
23         this.orderName = orderName;
24     }
25 
26     public Customer getCustomer() {
27         return customer;
28     }
29 
30     public void setCustomer(Customer customer) {
31         this.customer = customer;
32     }
33     
34     
35     
36 }
View Code

2、根据实体类创建对应的 hbm.xml文件

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 
 5 <hibernate-mapping>
 6     <class name="com.mcs.hibernate.entities.n21.Customer" table="CUSTOMERS">
 7         <id name="customerId" type="java.lang.Integer">
 8             <column name="CUSTOMER_ID" />
 9             <generator class="native" />
10         </id>
11         <property name="customerName" type="java.lang.String">
12             <column name="CUSTOMER_NAME" />
13         </property>
14     </class>
15 </hibernate-mapping>
View Code
 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 
 5 <hibernate-mapping package="com.mcs.hibernate.entities.n21">
 6     <class name="Order" table="ORDERS">
 7         <id name="orderId" type="java.lang.Integer">
 8             <column name="ORDER_ID" />
 9             <generator class="native" />
10         </id>
11         <property name="orderName" type="java.lang.String">
12             <column name="ORDER_NAME" />
13         </property>
14         
15         <!-- 
16             映射多对一的关联关系。 使用 many-to-one 来映射多对一的关联关系 
17             name: 多这一端关联的一那一端的属性的名字
18             class: 一那一端的属性对应的类名
19             column: 一那一端在多的一端对应的数据表中的外键的名字
20         -->
21         <many-to-one name="customer" class="Customer" column="CUSTOMER_ID"></many-to-one>
22     </class>
23 </hibernate-mapping>
View Code

3、备注:

  1、在多这一端使用 many-to-one 来映射多对一的关联关系,其中

    name: 多这一端关联的一那一端的属性的名字
    class: 一那一端的属性对应的类名
    column: 一那一端在多的一端对应的数据表中的外键的名字

  2、在新增时推荐先插入 1 的一端, 后插入 n 的一端

  3、在删除时,若不设定级联关系的情况下, 且 1 这一端的对象有 n 的对象在引用, 不能直接删除 1 这一端的对象

三、双向的多对一映射

1、创建Java实体类 

 1 package com.mcs.hibernate.entities.n21.both;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 public class Customer {
 7 
 8     private Integer customerId;
 9     private String customerName;
10     
11     /*
12      * 1. 声明集合类型时, 需使用接口类型, 因为 hibernate 在获取
13      * 集合类型时, 返回的是 Hibernate 内置的集合类型, 而不是 JavaSE 一个标准的
14      * 集合实现. 
15      * 2. 需要把集合进行初始化, 可以防止发生空指针异常
16      */
17     private Set<Order> orders = new HashSet<>();
18 
19     public Integer getCustomerId() {
20         return customerId;
21     }
22 
23     public void setCustomerId(Integer customerId) {
24         this.customerId = customerId;
25     }
26 
27     public String getCustomerName() {
28         return customerName;
29     }
30 
31     public void setCustomerName(String customerName) {
32         this.customerName = customerName;
33     }
34 
35     public Set<Order> getOrders() {
36         return orders;
37     }
38 
39     public void setOrders(Set<Order> orders) {
40         this.orders = orders;
41     }
42     
43     
44 
45 }
View Code
 1 package com.mcs.hibernate.entities.n21.both;
 2 
 3 public class Order {
 4     
 5     private Integer orderId;
 6     private String orderName;
 7     
 8     private Customer customer;
 9 
10     public Integer getOrderId() {
11         return orderId;
12     }
13 
14     public void setOrderId(Integer orderId) {
15         this.orderId = orderId;
16     }
17 
18     public String getOrderName() {
19         return orderName;
20     }
21 
22     public void setOrderName(String orderName) {
23         this.orderName = orderName;
24     }
25 
26     public Customer getCustomer() {
27         return customer;
28     }
29 
30     public void setCustomer(Customer customer) {
31         this.customer = customer;
32     }
33     
34     
35     
36 }
View Code

2、根据实体类创建对应的 hbm.xml文件 

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 
 5 <hibernate-mapping package="com.mcs.hibernate.entities.n21.both">
 6     <class name="Customer" table="CUSTOMERS">
 7         <id name="customerId" type="java.lang.Integer">
 8             <column name="CUSTOMER_ID" />
 9             <generator class="native" />
10         </id>
11         <property name="customerName" type="java.lang.String">
12             <column name="CUSTOMER_NAME" />
13         </property>
14         
15         <!-- 映射 1 对多的那个集合属性 -->
16         <!-- set: 映射 set 类型的属性, table: set 中的元素对应的记录放在哪一个数据表中. 该值需要和多对一的多的那个表的名字一致 -->
17         <!-- inverse: 指定由哪一方来维护关联关系. 通常设置为 true, 以指定由多的一端来维护关联关系 -->
18         <!-- cascade 设定级联操作. 开发时不建议设定该属性. 建议使用手工的方式来处理 -->
19         <!-- order-by 在查询时对集合中的元素进行排序, order-by 中使用的是表的字段名, 而不是持久化类的属性名  -->
20         <set name="orders" table="ORDERS" inverse="true" order-by="ORDER_NAME DESC">
21             <!-- 执行多的表中的外键列的名字 -->
22             <key column="CUSTOMER_ID"></key>
23             <!-- 指定映射类型 -->
24             <one-to-many class="Order"/>
25         </set>
26     </class>
27 </hibernate-mapping>
View Code
 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 
 5 <hibernate-mapping package="com.mcs.hibernate.entities.n21.both">
 6     <class name="Order" table="ORDERS">
 7         <id name="orderId" type="java.lang.Integer">
 8             <column name="ORDER_ID" />
 9             <generator class="native" />
10         </id>
11         <property name="orderName" type="java.lang.String">
12             <column name="ORDER_NAME" />
13         </property>
14         
15         <!-- 
16             映射多对一的关联关系。 使用 many-to-one 来映射多对一的关联关系 
17             name: 多这一端关联的一那一端的属性的名字
18             class: 一那一端的属性对应的类名
19             column: 一那一端在多的一端对应的数据表中的外键的名字
20         -->
21         <many-to-one name="customer" class="Customer" column="CUSTOMER_ID"></many-to-one>
22     </class>
23 </hibernate-mapping>
View Code

3、备注:

  1、在1的一端声明集合类型时,需使用接口类型,并把集合进行初始化, 可以防止发生空指针异常。

  2、在1的一端hbm.xml文件中需要映射 1 对多的那个集合属性(Set)  

    set: 映射 set 类型的属性, table: set 中的元素对应的记录放在哪一个数据表中. 该值需要和多对一的多的那个表的名字一致
    inverse: 指定由哪一方来维护关联关系. 通常设置为 true, 以指定由多的一端来维护关联关系 
    cascade 设定级联操作. 开发时不建议设定该属性. 建议使用手工的方式来处理 
    order-by 在查询时对集合中的元素进行排序, order-by 中使用的是表的字段名, 而不是持久化类的属性名

  

原文地址:https://www.cnblogs.com/maocs/p/4919968.html