hibernate级联保存更新、删除
2014-09-22 18:26
309 查看
1、级联保存和更新
当Hibernate持久化一个临时对象时,在默认情下,他不会自动持久化所关联的其他临时对象,如果希望当持久化对象时把他所关联的所有临时对象进行持久化的话,可以把的cascade属性设置为:"save-update" ,cascade的默认属性值为none。
cascade:设置操作对象时的级联操作,即层级之间的连锁操作,可取:
- save-update :表示当保存和更新当前对象(即insert和update语句时),会级联保存和更新与他关联的对象
- all :表示任何情况下都会进行级联操作,即对一个对象进行操作,也会对和他关联的其他对象进行同样的操作
- delete :表示在执行delete时,进行级联操作,删除和他关联的对象
- none :表示任何情况下,都不会进行级联操作
2、<set>元素的inverse属性:
在运行上面的程序时,如果hibernate的"show-sql"设置为true时,就会看到Hibernate会生成很多sql语句,其实很多sql语句都是重复的,为了解决这个问题,我们可以利用在<set>标签中加上inverse属性。术语:inverse是指反转的意思,在Hibernate中,表示关联关系中的方向关联关系中,inverse="false"的主控方,由主动方负责维护对象关系我们在customer对象的对象配置文件中加上
<set name="orders" cascade="save-update" inverse="true">
<key column="c_id" > </key>
<one-to-many class="net.mbs.mypack.Order " />
</set>
声明在Customer和Order的双向关联关系中,Customer端的关联只是Order端关联的镜象(即Order端是主空端,负责维护Customer和order对象之间的关联关系),当hibernate探测到持久化对象Customer或Order的状态发生变化时(主要是关联关系的改变),仅按照Order对象的状态的变化来同步更新数据库。
按次配置,如果在程序中,我们仅仅使用Customer.getOrder().add(order)(涉及了和Order的关联关系的改变),是不能让数据库跟对象的变化来进行数据库同步更新的,只有利用Order对象的方法改变的Order对象状态(eg:order.setCustomer(customer)----涉及到了和Customer的关联关系的改变)时,数据库才会根据变化来同步更新数据库,即只有主控方的状态(涉及到了和另一方面的关联关系的改变)发生了变化后,才会触发对象和数据库的同步更新。
实例:
Customer 和 Orders 是一对多的关系,Orders和Customer是多对一关系,即这两个双向关联.
Customer 和Bid是一对一的关系,一对一的关系就不存在双向和单向了
如下是他们的类:
customer.java
Java代码
package com.reflesh;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class Customer {
private int id;
private String name;
private Date date;
private String tele;
private Bid bidId;
private Set ordersId = new HashSet(); //省略set 和get 方法
}
orders.java
Java代码
public class Orders {
private Long orderId;
private String name;
private Customer customer;
Java代码
// 省略掉equals和haseCode()
Java代码
Bid.java
Java代码
<pre class="java" name="code">private Long bidId;
private String name;
private Customer customerBId;
}</pre>
Java代码
customer.hbm.xml
Java代码
<id name="id" column="customerId" type="int">
<generator class="sequence">
<param name="sequence">customerId</param>
</generator>
</id>
<property name="name" column="name" type="string" />
<property name="date" column="orderDate" type="date"/>
<property name="tele" column="telephone" type="string"/>
<set name="ordersId" cascade="save-update" inverse="true">
<key column="customerOId"/>
<one-to-many class="com.reflesh.Orders" />
</set>
<one-to-one name="bidId" class="com.reflesh.Bid" property-ref="customerBId" cascade="save-update"/>
orders.hbm.xml
Java代码
<id name="orderId" column="orderId2" type="long">
<generator class="sequence">
<param name="sequence">seq_order</param>
</generator>
</id>
<property name="name" column="name" type="string" />
<many-to-one
name="customer"
class="com.reflesh.Customer"
column="customerOId"
/>
bid.hbm.xml
Java代码
<id name="bidId" column="bidId" type="long">
<generator class="sequence" >
<param name="sequence">seq_bid</param>
</generator>
</id>
<property name="name" column="name" type="string" />
Java代码
<many-to-one name="customerBId" class="com.reflesh.Customer"
column="customerBId" unique="true" />
test.java
Java代码
Session session =HibernateSessionFactory.getSession();
Java代码
/* 关联类*/
Customer c = new Customer();
c.setName("bellwind");
Date date = RefleshActionHelper.FormatDate("2004-05-09", "yyyy-mm-dd");
c.setDate(date);
c.setTele("123456");
Serializable id = null;
Orders o = new Orders();
o.setName("订单1dfdf");
o.setCustomer(c);
Orders o2 = new Orders();
o2.setName("订单2");
o2.setCustomer(c);
c.getOrdersId().add(o);
c.getOrdersId().add(o2);
Bid bid = new Bid();
bid.setName("ijd");
bid.setCustomerBId(c);
c.setBidId(bid);
Java代码
/* 关联类完*/
try {
tr = session.beginTransaction();
id = session.save(c); //三个都保存
tr.commit();
} catch (Exception e) {
e.printStackTrace();
tr.rollback();
}
finally {
session.close();
}
return id;
说明:a,b,c为级联的步骤
a.在set属性上加 cascade="save-update"
b. 关联类 见代码test.java的注释
c. 保存customer一个就行了,因为customer表是主表,orders表的外键customerOId和Bid表的外键customerBId 都关系到customer表的主键;
注意:
a.一般都选择保存customer来级联保存orders和bids,不选择保存orders或者bids来级联保存customer;
b. 没有.inverse="true",执行如下语句
insert into customer (name, orderDate, telephone, customerId) values (?, ?, ?, ?)
Hibernate: insert into orders (name, customerOId, orderId2) values (?, ?, ?)
Hibernate: insert into orders (name, customerOId, orderId2) values (?, ?, ?)
Hibernate: insert into bid (name, customerBId, bidId) values (?, ?, ?)
Hibernate: update orders set customerOId=? where orderId2=?
Hibernate: update orders set customerOId=? where orderId2=?
有了inverse="true",执行如下语句
insert into customer (name, orderDate, telephone, customerId) values (?, ?, ?, ?)
Hibernate: insert into orders (name, customerOId, orderId2) values (?, ?, ?)
Hibernate: insert into orders (name, customerOId, orderId2) values (?, ?, ?)
Hibernate: insert into bid (name, customerBId, bidId) values (?, ?, ?)
可以看出减少了2条语句,提高了性能
customer单向关联orders的步骤:
1.
customer.hbm.xml
Java代码
<set name="ordersId" cascade="save-update" inverse="true">
<key column="customerOId"/>
<one-to-many class="com.reflesh.Orders" />
</set>
2.orders.hbm.xml 不用配关联到customer, 删除<many-to-one >元素
3.orders类的customer属性删除
4.只需单向关联
Customer c = new Customer();
Bid bid = new Bid();
c.setBidId(bid);
5.save(c) 就行了
注意:
如果是customer单向关联orders,那么inverse="true" 不可以少,否则orders表的外键为null,它需要
Hibernate: update orders set customerOId=? where orderId2=?
Hibernate: update orders set customerOId=? where orderId2=?
这两句来更新orders表的外键
当Hibernate持久化一个临时对象时,在默认情下,他不会自动持久化所关联的其他临时对象,如果希望当持久化对象时把他所关联的所有临时对象进行持久化的话,可以把的cascade属性设置为:"save-update" ,cascade的默认属性值为none。
cascade:设置操作对象时的级联操作,即层级之间的连锁操作,可取:
- save-update :表示当保存和更新当前对象(即insert和update语句时),会级联保存和更新与他关联的对象
- all :表示任何情况下都会进行级联操作,即对一个对象进行操作,也会对和他关联的其他对象进行同样的操作
- delete :表示在执行delete时,进行级联操作,删除和他关联的对象
- none :表示任何情况下,都不会进行级联操作
2、<set>元素的inverse属性:
在运行上面的程序时,如果hibernate的"show-sql"设置为true时,就会看到Hibernate会生成很多sql语句,其实很多sql语句都是重复的,为了解决这个问题,我们可以利用在<set>标签中加上inverse属性。术语:inverse是指反转的意思,在Hibernate中,表示关联关系中的方向关联关系中,inverse="false"的主控方,由主动方负责维护对象关系我们在customer对象的对象配置文件中加上
<set name="orders" cascade="save-update" inverse="true">
<key column="c_id" > </key>
<one-to-many class="net.mbs.mypack.Order " />
</set>
声明在Customer和Order的双向关联关系中,Customer端的关联只是Order端关联的镜象(即Order端是主空端,负责维护Customer和order对象之间的关联关系),当hibernate探测到持久化对象Customer或Order的状态发生变化时(主要是关联关系的改变),仅按照Order对象的状态的变化来同步更新数据库。
按次配置,如果在程序中,我们仅仅使用Customer.getOrder().add(order)(涉及了和Order的关联关系的改变),是不能让数据库跟对象的变化来进行数据库同步更新的,只有利用Order对象的方法改变的Order对象状态(eg:order.setCustomer(customer)----涉及到了和Customer的关联关系的改变)时,数据库才会根据变化来同步更新数据库,即只有主控方的状态(涉及到了和另一方面的关联关系的改变)发生了变化后,才会触发对象和数据库的同步更新。
实例:
Customer 和 Orders 是一对多的关系,Orders和Customer是多对一关系,即这两个双向关联.
Customer 和Bid是一对一的关系,一对一的关系就不存在双向和单向了
如下是他们的类:
customer.java
Java代码
package com.reflesh;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class Customer {
private int id;
private String name;
private Date date;
private String tele;
private Bid bidId;
private Set ordersId = new HashSet(); //省略set 和get 方法
}
orders.java
Java代码
public class Orders {
private Long orderId;
private String name;
private Customer customer;
Java代码
// 省略掉equals和haseCode()
Java代码
Bid.java
Java代码
<pre class="java" name="code">private Long bidId;
private String name;
private Customer customerBId;
}</pre>
Java代码
customer.hbm.xml
Java代码
<id name="id" column="customerId" type="int">
<generator class="sequence">
<param name="sequence">customerId</param>
</generator>
</id>
<property name="name" column="name" type="string" />
<property name="date" column="orderDate" type="date"/>
<property name="tele" column="telephone" type="string"/>
<set name="ordersId" cascade="save-update" inverse="true">
<key column="customerOId"/>
<one-to-many class="com.reflesh.Orders" />
</set>
<one-to-one name="bidId" class="com.reflesh.Bid" property-ref="customerBId" cascade="save-update"/>
orders.hbm.xml
Java代码
<id name="orderId" column="orderId2" type="long">
<generator class="sequence">
<param name="sequence">seq_order</param>
</generator>
</id>
<property name="name" column="name" type="string" />
<many-to-one
name="customer"
class="com.reflesh.Customer"
column="customerOId"
/>
bid.hbm.xml
Java代码
<id name="bidId" column="bidId" type="long">
<generator class="sequence" >
<param name="sequence">seq_bid</param>
</generator>
</id>
<property name="name" column="name" type="string" />
Java代码
<many-to-one name="customerBId" class="com.reflesh.Customer"
column="customerBId" unique="true" />
test.java
Java代码
Session session =HibernateSessionFactory.getSession();
Java代码
/* 关联类*/
Customer c = new Customer();
c.setName("bellwind");
Date date = RefleshActionHelper.FormatDate("2004-05-09", "yyyy-mm-dd");
c.setDate(date);
c.setTele("123456");
Serializable id = null;
Orders o = new Orders();
o.setName("订单1dfdf");
o.setCustomer(c);
Orders o2 = new Orders();
o2.setName("订单2");
o2.setCustomer(c);
c.getOrdersId().add(o);
c.getOrdersId().add(o2);
Bid bid = new Bid();
bid.setName("ijd");
bid.setCustomerBId(c);
c.setBidId(bid);
Java代码
/* 关联类完*/
try {
tr = session.beginTransaction();
id = session.save(c); //三个都保存
tr.commit();
} catch (Exception e) {
e.printStackTrace();
tr.rollback();
}
finally {
session.close();
}
return id;
说明:a,b,c为级联的步骤
a.在set属性上加 cascade="save-update"
b. 关联类 见代码test.java的注释
c. 保存customer一个就行了,因为customer表是主表,orders表的外键customerOId和Bid表的外键customerBId 都关系到customer表的主键;
注意:
a.一般都选择保存customer来级联保存orders和bids,不选择保存orders或者bids来级联保存customer;
b. 没有.inverse="true",执行如下语句
insert into customer (name, orderDate, telephone, customerId) values (?, ?, ?, ?)
Hibernate: insert into orders (name, customerOId, orderId2) values (?, ?, ?)
Hibernate: insert into orders (name, customerOId, orderId2) values (?, ?, ?)
Hibernate: insert into bid (name, customerBId, bidId) values (?, ?, ?)
Hibernate: update orders set customerOId=? where orderId2=?
Hibernate: update orders set customerOId=? where orderId2=?
有了inverse="true",执行如下语句
insert into customer (name, orderDate, telephone, customerId) values (?, ?, ?, ?)
Hibernate: insert into orders (name, customerOId, orderId2) values (?, ?, ?)
Hibernate: insert into orders (name, customerOId, orderId2) values (?, ?, ?)
Hibernate: insert into bid (name, customerBId, bidId) values (?, ?, ?)
可以看出减少了2条语句,提高了性能
customer单向关联orders的步骤:
1.
customer.hbm.xml
Java代码
<set name="ordersId" cascade="save-update" inverse="true">
<key column="customerOId"/>
<one-to-many class="com.reflesh.Orders" />
</set>
2.orders.hbm.xml 不用配关联到customer, 删除<many-to-one >元素
3.orders类的customer属性删除
4.只需单向关联
Customer c = new Customer();
Bid bid = new Bid();
c.setBidId(bid);
5.save(c) 就行了
注意:
如果是customer单向关联orders,那么inverse="true" 不可以少,否则orders表的外键为null,它需要
Hibernate: update orders set customerOId=? where orderId2=?
Hibernate: update orders set customerOId=? where orderId2=?
这两句来更新orders表的外键
相关文章推荐
- Hibernate级联保存和更新
- 数据库主键,外键,关系,级联保存、更新、删除
- Hibernate 数据的保存,更新和删除
- hibernate简单事例,注意事项,保存,更新,删除,session,Query,Criteria查询_Hql与Criteria查询的补充知识
- hibernate - 解决表结构外键限定为非空,级联保存和级联删除抛异常的问题
- hibernate多对多级联保存、级联删除
- 数据库主键,外键,关系,级联保存、更新、删除
- Hibernate级联保存与删除
- hibernate级联保存和更新
- 数据库主外键,级联的保存、更新和删除
- Hibernate级联保存和更新
- Hibernate中的级联保存更新cascade错误分析
- hibernate 一对多 级联 保存修改 删除
- Hibernate 数据的保存,更新和删除
- Hibernate级联保存和更新
- hibernate 级联删除报更新失败的问题
- Hibernate 一对多级联更新(更新,删除多方数据)的错误解决
- 【极客营】Hibernate完成CRM的联系人的保存操作-技术分析之级联删除
- 精通Hibernate——Session的保存、更新、删除和查询
- Hibernate级联保存和更新