hibernate映射-双向一对多映射

(当然双向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">

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

时间: 2024-10-25 13:05:19

hibernate映射-双向一对多映射的相关文章

hibernate映射-双向n-n关联关系

(学习记录,错误不足之处,请您耐心指正^_^) hibernate映射-双向n-n关联关系 一.代码示例: {类文件↓} Category.class package com.zit.hibernate.n2n.both; import java.util.HashSet; import java.util.Set; public class Category { private Integer id; private String name; private Set<Item> items

【SSH进阶之路】Hibernate映射——一对一双向关联映射(六)

上篇博文[SSH进阶之路]Hibernate映射--一对一单向关联映射(五),我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息.如图所示: 关键原因在于对象模型具有方向性: 单向:一端只能加载另一端,不能反过来. 双向:两端都可以加载另一端. 问题来了:如何我们想从身份证端(IdCard)加载人(Person),怎么办呢? 下面我们开始介绍一对一的双向关联映射. 映射原理 双向关联映射与单向关联映射的原理是一

Hibernate映射多对多双向关联关系(小案例)

多对多双向关联关系(Project(工程)/Emp(员工)为案例): 步骤如下: 1.创建Project类,并需要定义集合类型的Emp属性 public class Project { //编号 private Integer pid; //名称 private String pname; //定义集合类型的Emp属性 private Set<Emp> emps=new HashSet<Emp>(); public Integer getPid() { return pid; }

Hibernate一对一双向关联映射

关键原因在于对象模型具有方向性: 单向:一端只能加载另一端,不能反过来. 双向:两端都可以加载另一端. 问题来了:如何我们想从身份证端(IdCard)加载人(Person),怎么办呢? 下面我们开始介绍一对一的双向关联映射. 映射原理 双向关联映射与单向关联映射的原理是一样的,双向关联映射并不影响存储,只影响加载.所以,双向关联映射和单向关联映射的关系模型是一样的即数据库的表结构是一样的,只是IdCard的实体类和配置文件(IdCard.hbm.xml)发生了一点点变化. 对象模型 从上图中可以

【SSH系列】Hibernate映射 -- 一对多关联映射

    映射原理       一对多关联映射和多对一关联映射的映射原理是一样一样的,所以说嘛,知识都是相通的,一通百通,为什么说一对多关联映射和多对一关联映射是一样的呢?因为她们都是在多的一端加入一个外键,指向一的一段,关联关系都是在多的一端进行维护,只是我们在写映射的时候发生了变化.       一对多和多对一的映射原理是一样的,但是她们之间也存在着小小的区别,毕竟世界上没有两片完全相同的叶子,她们之间的区别就是维护的关系不同,我们先来看多对一,多端维护一端的关系,在加载多端的时候,可以将一端

Hibernate映射( 多对一、一对一、一对多、多对多)的配置方法

hihernate一对多关联映射(单向Classes----->Student) 一对多关联映射利用了多对一关联映射原理 多对一关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是多指向一一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多 也就是说一对多和多对一的映射策略是一样的,只是站的角度不同 在一一端维护关系的缺点: * 如果将t_student表里的classesid字段设置为非空,则无法保存 * 因为不是在student这一端维护关系,所以student

Hibernate 单向/双向 多对多

Hibernate的多对多从单向和双向来分就是单向多对多和双向多对多两种. Hibernate的双向多对多 先来说一下什么是多对多的关系,举个例子,老师和学生,老师有语文老师,数学老师,英语老师等等,学生可以是1班的学生也可以是2班的学生,对于每个学生而言,他有多个老师给他讲课,而对于每一个老师而言,他要授课的学生也有很多,像这样的情况就可以描述成多对多了.即两个表之间,每一个表中的记录都对应另一个表的部分或全部记录的集合,这种情况就是多对多关系,而单向多对多与双向多对多的不同在于单向只是一方的

Hibernate映射解析——关联映射(一)

上篇我们谈到了Hibernate的基本映射,接下来为大家介绍Hibernate的多对一关联映射. 多对一关联映射:在多的一端加了个外键,外键指向一的一端,这样的好处是让Hibernate访问多的一端的时候,自动把1端给加上. 对象模型图: 关系模型图: 多对一关联映射主要是靠下面一句来进行维护,即在多的一端加上如下标签 <many-to-noe name="group"  column="groupid"/> User.hbm.xml配置文件: <

Hibernate映射解析——关联映射(二)

在前一篇文章,我们说了多对一和一对多映射原理是一样的,都是在多的一端加入一个外键指向一的一端. 区别在于维护的关系不同. 多对一维护的关系:多指向一的关系,如果维护了多指向一的关系,那么加载多的时候会把一加载上来 一对多维护的关系:一指向多的关系,如果维护了一指向多的关系,那么加载一的时候会把多加载上来 一对多映射包含两种映射方式: 1.单向一对多 对象模型图: 关系模型图: Classes.hbm.xml配置文件 <?xml version="1.0"?> <!DO