hibernate 的级联保存和关联关系

    技术2026-09-21  9

    转自:http://joezheng123.javaeye.com/blog/346877

     

    当Hibernate持久化一个临时对象时,在默认情下,他不会自动持久化所关联的其他临时对象,如果希望当持久化对象时把他所关联的所有临时对象进行持久化的话:可以把 的cascade属性设置为"save-update" ,cascade的默认属性值为none。 cascade:设置操作对象时的级联操作,即层级之间的连锁操作 值 save-update :表示当保存和更新当前对象(即insert和update语句时),会级联保存和更新与他关联的对象 值 all :表示任何情况下都会进行级联操作,即对一个对象进行操作,也会对和他关联的其他对象进行同样的操作 值 delete :表示在执行delete时,进行级联操作,删除和他关联的对象 值 none :表示任何情况下,都不会进行级联操作

     

    以下为实例代码:

    Customer 和 Orders 是一对多的关系,Orders和Customer是多对一关系,即这两个双向关联.

    Customer 和Bid是一对一的关系,一对一的关系就不存在双向和单向了

     

    如下是他们的类:

    customer.java

    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

    public class Order { private Long orderId; private String name; private Customer customer; }

     

    Bid.java

    public class Bid { private Long bidId; private String name; private Customer customerBId; }

     

    customer.hbm.xml

    <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"> </one-to-one>  

     

    orders.hbm.xml

    <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"> </many-to-one> 

     

    bid.hbm.xml

    <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" /> <many-to-one name="customerBId" class="com.reflesh.Customer" column="customerBId" unique="true"> </many-to-one>  

     

    test.java

    Session session = HibernateSessionFactory.getSession(); Transaction tr = null;

     

    /* 关联类 */ 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);

     

    /* 关联类完 */ 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

    <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表的外键

     

     

     

    最新回复(0)