做加工都在哪个网站推广,企业展厅布置效果图大全,网站名称需要用注册吗,梁志天设计公司官网首页Hibernate集合映射中#xff0c;经常会使用到inverse和cascade这两个属性。对于我这样#xff0c;Hibernate接触不深和语文水平够烂的种种因素#xff0c;发现这两个属性实在是难以理解#xff0c;无奈只好将这个两个属性解释工作交给了Google和Ba…Hibernate集合映射中经常会使用到inverse和cascade这两个属性。对于我这样Hibernate接触不深和语文水平够烂的种种因素发现这两个属性实在是难以理解无奈只好将这个两个属性解释工作交给了Google和Baidu查看了许多牛人的解释加上自己在Eclipse上的调试对inverse和cascade这两个属性有了一定的见解。 inverse属性探究 inverse-直译过来就是反转使颠倒的意思书面化的解释为是否将关系维护的权力交给对方这个解释真够蛋疼的-_-!!就是理解不了。 Hibernate中的inverse属性只有两个值true和false。true表示将关系维护的权力交给对方false表示不交出维护权力默认值。 例如有两张表customer和orders他们的关系是一对多customer是一方orders为多方。 drop table if exists customer drop table if exists orders create table customer ( id varchar(255) not null, username varchar(255), password varchar(255), age integer, register_time datetime, primary key (id) ) create table orders ( id varchar(255) not null, orderNumber varchar(255), balance integer, customer_id varchar(255), primary key (id) ) 两表对应的hbm文件对应的POJO类 /*customer表对应的POJO类*/ public class Customer { private String id; private String username; private String password; private Timestamp registerTime; private int age; private SetOrder orders new HashSetOrder(); public Customer() { } /*get and set method*/ } /*orders表对应的POJO类*/ public class Order { private String id; private String orderNumber; private int balance; private Customer customer; public Order() { } /* get and set method*/ } !--Customer类的hbm文件-- hibernate-mapping class namecom.suxiaolei.hibernate.pojos.Customer tablecustomer id nameid typestring column nameid/column generator classuuid/generator /id property nameusername columnusername typestring/property property namepassword columnpassword typestring/property property nameage columnage typeinteger/property property nameregisterTime columnregister_time typetimestamp/property set nameorders inversetrue cascadeall key columncustomer_id /key one-to-many classcom.suxiaolei.hibernate.pojos.Order/ /set /class /hibernate-mapping !--Order类的hbm文件-- hibernate-mapping class namecom.suxiaolei.hibernate.pojos.Order tableorders id nameid typestring column nameid/column generator classuuid/generator /id property nameorderNumber columnorderNumber typestring/property property namebalance columnbalance typeinteger/property many-to-one namecustomer classcom.suxiaolei.hibernate.pojos.Customer column namecustomer_id/column /many-to-one /class /hibernate-mapping下面写一些测试代码测试inverse属性的特性 情况一将inverse设置为true让多方维护关系 try { tx session.beginTransaction(); /* * 创建Customer对象并设置其属性值 */ Customer customer new Customer(); customer.setUsername(zhangsan); customer.setPassword(123456); customer.setAge(22); customer.setRegisterTime(new Timestamp(new Date().getTime())); /* * 创建Order对象order1并设置其属性值 */ Order order1 new Order(); order1.setOrderNumber(a1a2a3); order1.setBalance(1000); order1.setCustomer(customer);//将customer对象关联到order1对象上 /* * 创建Order对象order2并设置其属性值 */ Order order2 new Order(); order2.setOrderNumber(d3d2d1); order2.setBalance(670); order2.setCustomer(customer);///将customer对象关联到order2对象上 customer.getOrders().add(order1);//将order1对象关联到customer对象上 customer.getOrders().add(order2);//将order2对象关联到customer对象上 session.saveOrUpdate(customer); tx.commit(); } catch (Exception e) { if(tx ! null) { tx.rollback(); } e.printStackTrace(); } finally { session.close(); } 数据库中的数据更新为 customer表 orders表 现在将order1.setCustomer(customer);这段代码注释掉再次运行程序 customer表 orders表 可以到看到显著地差别了第一次保存id402881e534ea7c750134ea7c76bc0001的数据时orders表中插入了两条数据他们的customer_id都为customer中对应记录的主键值而第二次保存记录id402881e534ea81be0134ea81bfea0001的数据时由于先前将原来的代码段order1.setCustomer(customer);注释掉了此时order表中插入的数据中order1代表的那条记录没有customer_id值。 从以上现象可以有助于理解inverse这个属性。首先inverse控制关系维护权力那么什么是关系关系的具体体现是什么在以上例子中关系就是两个表之间的关系通常为一对多,一对一,多对多三种关系,而关系的具体体现为orders表中的 customer_id列而inverse属性就是告诉Hibernate哪一方有权力管理和维护这一列。上面的例子将inverse设置为 true那么customer_id这一列由多方order对象维护。这说明了只有order对象对关系的操作会反映到数据库中。对象对关系的操作就是对关联属性的操作例如order对象对自身的customer属性操作customer对象对自身的orders集合SetOrder操作 例如将id402881e534ea7c750134ea7c76bc0001的customer对象从数据库中取出获取到该customer对象所关联的order对象集合将该customer对象所关联的order对象删除。 Customer customer (Customer)session.get(Customer.class, 402881e534ea7c750134ea7c76bc0001); Order order (Order)session.get(Order.class, 402881e534ea7c750134ea7c76ce0002); System.out.println(customer association order count:customer.getOrders().size()); customer.getOrders().remove(order); System.out.println(customer association order count:customer.getOrders().size()); session.saveOrUpdate(customer); //Console Output: customer association order count:2customer association order count:1 可以看到customer中关联的order对象集合确实有对象被删除了若操作有效表示该order对象与customer对象没有关系了反映到数据库中应该将该order对象对应的customer_id设置为null。现在查看一下数据库数据 看到了吧刚刚那个操作就是个无用操作不会反应到数据库中。我们修改一下程序代码 Customer customer (Customer)session.get(Customer.class, 402881e534ea7c750134ea7c76bc0001); Order order (Order)session.get(Order.class, 402881e534ea7c750134ea7c76ce0002); order.setCustomer(null); session.saveOrUpdate(customer); 这次我们使用order对象来操作关系将该order对象与customer对象脱离关系若操作有效则反映在数据库中应该是该order对象的customer_id字段的值变成null,现在查看一下数据库 可以看到此次操作成功的反映到了数据库中了。 情况二将inverse属性设置为false双方都维护关系因为没有一方交出权力inverse的默认值为false而且inverse属性只能在set、list、map等几个标签中设置像many-to-one这一类的标签都不能设置inverse这个属性值它们只能取值false 这里会产生书中所说的性能问题囧这个也是理解了很久很久这个不管怎么说你都可能理解不了我就是这样的-_-!!所以我建议使用第三方的软件将Hibernate输出的SQL语句的绑定值显示出来可以参考这里。之所以会产生性能为题当你操作关系是会无故多产生一些update语句比如你使用上面的例子保存一个customer对象它关联了2个order对象它不但会生成3条insert语句用于插入数据还会生成2条update语句将关联的order对象的customer_id更新为自己的主键值你想想要是一个customer对象包含几万了order对象购物狂那么每次保存它得要多生成几万条update语句这个就是很严重的性能问题了。 为什么Hibernate会产生update语句呢那是Hibernate太主动太热情太负责的表现它怕你出现错误例如有几万个order对象需要关联到customer对象上这就需要调用order.setCustomer(customer);几万个对象这不是人可以不放错的完成的。所以Hibernate怕你出错忘记调用这个方法所以他将会在order对象保存完毕后将所有关联对象的customer_id字段更新一遍确保正确性这样也就产生上面的性能问题。 将inverse设置为false后你可以尝试设置order1.setCustomer(null),它依然会正确的将customer的主键值完美的插入到order的customer_id字段上只是会多一条update语句。 cascade属性 cascade-直译过来就是级联、串联的意思书面化的解释为该属性会使我们在操作主对象时同时Hibernate帮助我们完成从属对象相应的操作比如有Customer和Order这两张表关系为一对多只使用JDBC删除Customer表中的一行记录时我们还需要手动的将Order表中与之关联的记录全都删除使用Hibernate的cascade属性后当我们删除一条Customer记录时Hibernate会帮助我们完成相应Order表记录的删除工作方便了我们的工作。 总 结 使用inverse这个属性时要考虑清楚关系不然你的系统就会有大的性能问题书本上和一些牛人建议关系一般由多方维护当遇到多对多时怎么办其实多对多久是两个一对多随意设置一方inverse为true就可以了不要两方都设置或都不设置囧我开始就是死板这样的设置。而是用cascade属性时主对象(一方)一般设置为all而多方不建议设置包含delete操作的选项建议设置多方为save-update这是因为你删除一方多方已经没有存在的意义了而删除多方不能代表一方没意义了例如消费者和订单。最后cascade操作的是两张表的记录或两端的对象而inverse操作的是两张表的关系或两个对象的关系。转载于:https://www.cnblogs.com/suding1188/archive/2013/01/04/2844575.html