对多的关联关系也是最常见的对象之间的关系, 比如一个班级有很多个学生, 一个公司有很多部门,一个部门有很多雇员,一份债务(Credit)对应多个现金流(Cashflow),一个人有多个小孩, 一个客户有多张订单等等。
为了演示one-to-many,继续重用前面的对象Member会员,一个Member对象可以下多个订单Order,先添加一个订单类:
修改Member对象,给它添加一个属性orders,表示该Member对象持有的订单。
对应的数据库中的表myorder (本来我喜欢把表名和对象名保持一致, 但是因为在sqlserver2000中order是关键字,所以用myorder作表名) 有一个字段member_id和member表的id关联。下面是dml语句和映射文件。
Member.hbm.xml:
Order.hbm.xml:
修改一下MemberHibernateDao的测试用例main函数来测试看对Member 进行操作的时候可不可以成功的操作orders。
一切工作正常,遥测信号正常。(BS一下)。
但是有一个问题:Member和Order是一对多单向关联关系,通过Member可以获得orders, 但是通过Order却不能获得member。于是在给Member添加一个订单Order的时候, 需要先获得orders集合, 然后orders.add(new Order); 然后调save方法。而且更要命的是,观察一下hibernate输出的SQL会发现,为了添加一条order, 居然产生了两条sql语句:
insert into hibernate.dbo.myorder (total_price, member_id) values (?, ?) select scope_identity()
update hibernate.dbo.myorder set member_id=? where id=?
这样严重影响了数据库的性能。如果Order可以知道Member的存在,那问题就好办了,于是, 有了双向关联。
现在动手改善一下代码和配置文件,以形成双向关联。修改Order.java,添加一个属性member。
修改一下Order.hbm.xml, 使Order可以反向关联到Member:
修改一下Member.hbm.xml的orders配置,inverse="true"的意思是Member不再主控和order的关系, 由Order来控制它和Member的关系,这样的话,Order会去主动感知Member。
修改测试用例重新测试:
再次观察sql输出会发现插入order只需要1条sql。