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

    技术2022-05-11  145

     

    下面有两张表: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);


    最新回复(0)