Hibernate HelloWorld-07 双向多对一的映射关系

来源:互联网 发布:用友crm软件 编辑:程序博客网 时间:2024/05/24 04:54

一、双向一对多关系

1、从 Order 到 Customer 的多对一 双向关联,需要在Order 类中定义一个 Customer 属性, 而在 Customer 类中需定义存放 Order 对象的集合属性。

2、双向 1-n 与 双向 n-1 是完全相同的两种情形

3、双向 1-n 需要在 1 的一端可以访问 n 的一端, 反之依然


二、注意

1、当 Session 从数据库中加载 Java 集合时, 创建的是 Hibernate 内置集合类的实例, 因此在持久化类中定义集合属性时必须把属性声明为 Java 接口类型

2、Hibernate 的内置集合类具有集合代理功能, 支持延迟检索策略

3、事实上, Hibernate 的内置集合类封装了 JDK 中的集合类, 这使得 Hibernate 能够对缓存中的集合对象进行脏检查, 按照集合对象的状态来同步更新数据库。

4、在定义集合属性时, 通常把它初始化为集合实现类的一个实例. 这样可以提高程序的健壮性, 避免应用程序访问取值为 null 的集合的方法抛出 NullPointerException

5、Hibernate 使用 <set> 元素来映射 set 类型的属性

6、<key> 元素设定与所关联的持久化类对应的表的外键column: 指定关联表的外键名

7、<one-to-many> 元素设定集合属性中所关联的持久化类class: 指定关联的持久化类的类名


三、set元素的属性

1、inverse属性

  • 在hibernate中通过对 inverse 属性的来决定是由双向关联的哪一方来维护表和表之间的关系. 
  • inverse = false 的为主动方,inverse = true 的为被动方, 由主动方负责维护关联关系在没有设置 inverse=true 的情况下,父子两边都维护父子关系 
  • 在 1-n 关系中,将 n 方设为主控方将有助于性能改善(如果要国家元首记住全国人民的名字,不是太可能,但要让全国人民知道国家元首,就容易的多)
  • 在 1-N 关系中,若将 1 方设为主控方会额外多出 update 语句。
  • 插入数据时无法同时插入外键列,因而无法为外键列添加非空约束

2、cascade 属性

在对象 – 关系映射文件中, 用于映射持久化类之间关联关系的元素, <set>, <many-to-one> 和 <one-to-one> 都有一个 cascade 属性, 

它用于指定如何操纵与当前对象关联的其他对象.


3、order-by 属性

<set> 元素有一个 order-by 属性, 如果设置了该属性, 当 Hibernate 通过 select 语句到数据库中检索集合对象时, 利用 order by 子句进行排序

order-by 属性中还可以加入 SQL 函数

四、代码

package com.weixuan.hibernate;import java.util.HashSet;import java.util.Set;public class Customer {private Integer CustomerID;private String CustomerName;//添加集合引用/** * 1、声明集合类型时,需要使用接口类型,因为hibernate在获取集合类型时,返回的是hibernate内置的集合类型,而不是javase标准集合 * 2、需要把集合初始化,防止空指针异常 */private Set<Order> sorder = new HashSet<Order>();public Set<Order> getSorder() {return sorder;}public void setSorder(Set<Order> sorder) {this.sorder = sorder;}public Integer getCustomerID() {return CustomerID;}public void setCustomerID(Integer customerID) {CustomerID = customerID;}public String getCustomerName() {return CustomerName;}public void setCustomerName(String customerName) {CustomerName = customerName;}@Overridepublic String toString() {return "Customer [CustomerID=" + CustomerID + ", CustomerName="+ CustomerName + ", sorder=" + sorder + "]";}}

package com.weixuan.hibernate;/* * 从 Order 到 Customer 的多对一双向关联,需要在Order 类中定义一个 Customer 属性,  * 而在 Customer 类中需定义存放 Order 对象的集合属性 */public class Order {private Integer OrderId;private String OrderName;private Customer customer;public Integer getOrderId() {return OrderId;}public void setOrderId(Integer orderId) {OrderId = orderId;}public String getOrderName() {return OrderName;}public void setOrderName(String orderName) {OrderName = orderName;}public Customer getCustomer() {return customer;}public void setCustomer(Customer customer) {this.customer = customer;}@Overridepublic String toString() {return "Order [OrderId=" + OrderId + ", OrderName=" + OrderName+ ", customer=" + customer + "]";}}

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Generated 2015-6-1 21:16:16 by Hibernate Tools 3.4.0.CR1 --><hibernate-mapping package="com.weixuan.hibernate"><class name="Customer" table="CUSTOMERS"><id name="CustomerID" type="java.lang.Integer"><column name="CUSTOMER_ID" /><generator class="native" /></id><property name="CustomerName" type="java.lang.String"><column name="CUSTOMER_NAME" /></property><!-- 映射一对多的那个集合 --><!-- set 映射set类型的属性 private Set<Order> sorder = new HashSet<Order>(); table:set中对应的记录放在哪一个表,和多对一中的多的那个表一致 --><set name="sorder" table="ORDERS"><!-- 指定多的表中的外键列的名字 --><key column="CUSTOMER_ID"></key><!-- 指定映射类型 --><one-to-many class="Order" /></set></class></hibernate-mapping>

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Generated 2015-6-1 19:18:30 by Hibernate Tools 3.4.0.CR1 --><hibernate-mapping package="com.weixuan.hibernate"><class name="Order" table="ORDERS"><id name="OrderId" type="java.lang.Integer"><column name="ORDER_ID" /><generator class="native" /></id><property name="OrderName" type="java.lang.String"><column name="ORDER_NAME" /></property><many-to-one name="customer" class="Customer" column="CUSTOMER_ID" ></many-to-one></class></hibernate-mapping>

package com.weixuan.hibernate.test;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;import com.weixuan.hibernate.Customer;import com.weixuan.hibernate.Order;public class TestHibernateNtoOne {private SessionFactory sessionFactory = null;private Session session = null;private Transaction transaction = null;@Beforepublic void init() {Configuration configuation = new Configuration().configure();ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuation.getProperties()).buildServiceRegistry();sessionFactory = configuation.buildSessionFactory(serviceRegistry);session = sessionFactory.openSession();transaction = session.beginTransaction();}@Afterpublic void Destory() {transaction.commit();session.close();sessionFactory.close();}@Testpublic void testManyToOneSave() {Customer customer = new Customer();customer.setCustomerName("AAA");Order order1 = new Order();order1.setOrderName("order1");Order order2 = new Order();order2.setOrderName("order2");// 设定关联关系order1.setCustomer(customer);order2.setCustomer(customer);// 双向customer.getSorder().add(order1);customer.getSorder().add(order2);/** * 1、先插入customer,然后是order是三条insert语句 */// 执行save方法session.save(customer);session.save(order1);session.save(order2);/* * Customer customer1 = new Customer(); * customer1.setCustomerName("BBB"); *  * Order order3 = new Order(); order3.setOrderName("order3"); Order * order4 = new Order(); order4.setOrderName("order4"); *  * order3.setCustomer(customer1); order4.setCustomer(customer1); *//** * 2、先插入order,然后是customer,是两条update语句,三条insert语句 */// 执行save方法// session.save(order3);// session.save(order4);// session.save(customer1);}}






0 0
原创粉丝点击