Hibernate二次笔记 表的相互关联 inverse反转

来源:互联网 发布:保定三金网络怎么样 编辑:程序博客网 时间:2024/05/01 01:49

 

下面有两张表:1.CUSTOMER    ID (PK)      2.ORDERS          ID C_ID(FK)

下面是两表之间的代码:

 try {
            
// Create some data and persist it
            tx = session.beginTransaction();

            Customer customer 
= new Customer("Tom"new HashSet());
            Order order 
= new Order();
            order.setOrderNumber(
"Tom_Order001");

            order.setCustomer(customer); 
//将订单中的所属人属性加入
            customer.getOrders().add(order);
//取得用户订单list,追加新订单

            session.save(customer);
            tx.commit();
        } 

而这两句话就相当于在hibernate中产生两条SQL语句:

UPDATE ORDERS SET ORDER_NUMBER='?', CUSTOMER_ID=WHERE ID=?;
UPDATE ORDERS SET CUSTOMER_ID=WHERE ID=?;

但这两条代码的功能是一样的,只是修改了一条ORDERS表的一条记录。

其实原理是这样的:

1.建立Orders对象到Customer对象的多对一关联关系:order.setCustomer(customer);

hibernate后台产生的SQL:UPDATE ORDERS SET ORDER_NUMBER='?', CUSTOMER_ID=WHERE ID=?;

2.建立Customer对象到Order对象的一对多关联关系:customer.getOrders().add(order);

hibernate后台产生的SQL:UPDATE ORDERS SET CUSTOMER_ID=WHERE ID=?;

重复执行多余的SQL语句会影响JAVA应用的性能,解决这一问题的办法是把<set>元素的inverse属性设为true,该属性的默认值为false:

     <set 
        
name="orders"
        inverse
="true"
        cascade
="save-update" 
        
>
        
        
<key column="CUSTOMER_ID" />
        
<one-to-many class="mypack.Order" />
     
</set>    

反转属性,这时Customer端的关联只是Order端关联的镜像。这里Hibernate只会生成一条SQL语句:UPDATE ORDERS SET ORDER_NUMBER='?', CUSTOMER_ID=WHERE ID=?;

即便注释掉了//customer.getOrders().add(order);也不会影响到hibernate的执行;反之,注释掉//order.setCustomer(customer); Hibernate将不会执行任何SQL。但还是推荐在程序中代码写入双关联,增加程序的健壮性,不会受到hibernate的影响。

另外解除关联的原理也是一样:customer.getOrders().remove(order);  order.setCustomer(null);

原创粉丝点击