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>
二、单向的多对一映射
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 }
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 }
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>
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>
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 }
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 }
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>
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>
3、备注:
1、在1的一端声明集合类型时,需使用接口类型,并把集合进行初始化, 可以防止发生空指针异常。
2、在1的一端hbm.xml文件中需要映射 1 对多的那个集合属性(Set)
set: 映射 set 类型的属性, table: set 中的元素对应的记录放在哪一个数据表中. 该值需要和多对一的多的那个表的名字一致
inverse: 指定由哪一方来维护关联关系. 通常设置为 true, 以指定由多的一端来维护关联关系
cascade 设定级联操作. 开发时不建议设定该属性. 建议使用手工的方式来处理
order-by 在查询时对集合中的元素进行排序, order-by 中使用的是表的字段名, 而不是持久化类的属性名