码迷,mamicode.com
首页 > Web开发 > 详细

hibernate映射-双向一对多映射

时间:2015-12-25 14:57:45      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:

(当然双向1-n与双向n-1是完全相同的。)

双向1-n需要在1的一端访问n的一端,同时,n的一端也可以访问1的一端。

举例:Customer-Order

一、代码演示:

{类文件↓}

 Customer:

技术分享
 1 import java.util.HashSet;
 2 import java.util.Set;
 3 
 4 public class Customer {
 5     
 6     private Integer customerId;
 7     private String customerName;
 8     
 9     
10     /**
11      * 1. 此处的集合类型必须要用 接口类型,后面会发现读取orders 的类型是org.hibernate.collection.internal.PersistentSet
12      *         一个hibernate内置的一个集合类,是set的子类
13      * 2. 此处需要将集合进行初始化,防止空指针异常
14      */
15     private Set<Order> orders = new HashSet<>();
16     
17     
18     public Set<Order> getOrders() {
19         return orders;
20     }
21     public void setOrders(Set<Order> orders) {
22         this.orders = orders;
23     }
24     
25     
26     public Integer getCustomerId() {
27         return customerId;
28     }
29     public void setCustomerId(Integer customerId) {
30         this.customerId = customerId;
31     }
32     public String getCustomerName() {
33         return customerName;
34     }
35     public void setCustomerName(String customerName) {
36         this.customerName = customerName;
37     }
38     
39 }    
Customer.class

Order:

技术分享
 1 public class Order {
 2     
 3     private Integer orderId;
 4     private String orderName;
 5     
 6     private Customer customer;
 7 
 8     public Integer getOrderId() {
 9         return orderId;
10     }
11 
12     public void setOrderId(Integer orderId) {
13         this.orderId = orderId;
14     }
15 
16     public String getOrderName() {
17         return orderName;
18     }
19 
20     public void setOrderName(String orderName) {
21         this.orderName = orderName;
22     }
23 
24     public Customer getCustomer() {
25         return customer;
26     }
27 
28     public void setCustomer(Customer customer) {
29         this.customer = customer;
30     }
31     
32 }
Order.class

 {映射文件↓}

hbm.xml配置文件中,并没有相应的<one-to-many>属性,而是用<set>来代替,而<set>的子元素中,有<one-to-many>子元素

Customer.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 <!-- Generated 2015-11-29 10:18:07 by Hibernate Tools 3.4.0.CR1 -->
 5 <hibernate-mapping package="com.zit.hibernate.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 name="orders" table="ORDERS" inverse="true" cascade="delete">
17             <key column="CUSTOMER_ID"></key>
18             <one-to-many class="Order"/>
19         </set>
20         
21     </class>
22 </hibernate-mapping>
Customer.hbm.xml

 

注意:

1 <set name="orders" table="ORDERS" inverse="true" cascade="delete">
2     <key column="CUSTOMER_ID"></key>
3     <one-to-many class="Order"/>
4 </set>

<set>  name是1的一端的包含的n的一端的属性名;table=“”是表名,参照的是ORDERS表,得跟Orders.hbm.xml中的那个表名一致。

<key> 子元素中的column=“”要与  Orders.hbm.xml 中的 <many-to-one>中的<column/>对应一致。

(务必注意这两个一一对应关系)

<one-to-many> 对应n的一端的类全类名。要指明是one-to-many类型,因为many-to-many也是用set来表示的。

 

 

Order.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 <!-- Generated 2015-11-29 10:18:07 by Hibernate Tools 3.4.0.CR1 -->
 5 <hibernate-mapping package="com.zit.hibernate.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         <many-to-one name="customer" class="Customer">
15             <column name="CUSTOMER_ID" />
16         </many-to-one>
17     </class>
18 </hibernate-mapping>
Order.hbm.xml

 

二、使用注意:

1.插入数据时:

   先保存1的一端的数据,再保存多的一端的数据,若反之,则会多出UPDATE语句。(此处会多出的UPDATE是在单向n- 1中,会多的UPDATE语句数量的两倍,因为双向1-n两边都会维护关联关系)

   但是这种双向关联,在插入时,会有UPDATE语句产生,这与单向的n-1不同,在单向的n-1关联关系中,若用户先插入1的一端,再插入n的一端,是不会出现UPDATE语句的。在双向1-n关联关系中,若先插入1的一端,再插入多的一端,UPDATE会相应少,数目为插入的多的一端的数据数目。反之,若先插入n的一端,再插入1的一端,则UPDATE语句数目会是前者的两倍。

[双方都维护关联关系,会降低程序效率。可以通过设置 inverse 属性来决定是由双向关联中的哪一方来维护表和表之间的关联关系。inverse = false 的为主动方,inverse=true的为被动方。若未设置inverse=true,则双方都维护。

 在1-n关系中,将n方设置为主控方将有助于性能改善,见Customer.hbm.xml中的设置]

  session.save(object);

2.在Customer.class中,需要将set<Order>进行初始化,即:

  Set<Order> orders = new HashSet<>();

  否则会出现空指针异常。

3.延迟加载:

   在获取了Customer的对象后,customer.getOrders().getClass()返回的是一个hibernate内置的

   集合类型:PersistentSet,该类型具有延迟加载和存放代理对象的功能。是Java.Util.Set接口的一个实现类。

   这也表明了在声明定义几何属性时必须把属性声明为Java接口类型,如Set,而不能是HashSet

4.懒加载异常:LazyInitializationException

5.在需要使用集合中元素的时候才进行初始化,而使用集合的size()的时候都不会进行初始化。

6.<set>中配置 order-by,让集合内的元素按指定的属性,升序、降序排列,

   例:<set order-by="ORDER_NAME DESC">

   注意:这里使用的是表中的字段名,而不是持久化类的属性名。

hibernate映射-双向一对多映射

标签:

原文地址:http://www.cnblogs.com/zitt/p/5073524.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!