转:http://www.iteye.com/topic/766211
public class Customer { private int id; private String name; private Set orders = new HashSet(); }
即Customer类具有一个set集合属性orders,其中Order类定义如下:
public class Order { private int id; private String orderName; }
数据库中表的结构:
t_customer: 两个字段: id name
t_order: 三个字段: id orderName customerid
Customer类的映射文件:Customer.hbm.xml
<hibernate-mapping> <class name="test.Customer" table="t_customer" lazy="false"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <set name="orders" cascade="save-update" lazy="false"> <key column="customerid"/> <one-to-many class="test.Order"/> </set> </class> </hibernate-mapping>
执行如下代码:
Set orders = new HashSet(); Order o1 = new Order(); o1.setOrderName("o1"); Order o2 = new Order(); o2.setOrderName("o2"); orders.add(o1); orders.add(o2); Customer c = new Customer(); c.setName("aaa"); c.setOrders(orders); session.save(c);
此时Hibernate发出的sql语句如下:
Hibernate: insert into t_customer (name) values (?) Hibernate: insert into t_order (orderName) values (?) Hibernate: insert into t_order (orderName) values (?) Hibernate: update t_order set customerid=? where id=? Hibernate: update t_order set customerid=? where id=?
查看数据库:
t_customer : t_order:
id | name id | orderName | customerid
1 aaa 1 o1 1
2 o2 1
分析:保存Customer对象时,首先发出insert into t_customer (name) values (?)语句将c同步到数据库,由于在<set>映射中设置cascade="save-update",所以会级联保存orders集合中的 Order类型的o1,o2对象。
现在set映射中设置 inverse="true" ,再次执行上述代码,查看sql语句:
Hibernate: insert into t_customer (name) values (?) Hibernate: insert into t_order (orderName) values (?) Hibernate: insert into t_order (orderName) values (?)
相比上一次执行,少了两条update语句,查看数据库:
t_customer : t_order:
id | name id | orderName | customerid
1 aaa 1 o1 NULL
2 o2 NULL
发现t_order表中customerid的值为NULL,这是由于设置了inverse="true",它意味着
Customer不再作为主控方,而将关联关系的维护工作交给关联对象Orders来完成。在保存Customer 时,Customer不在关心Orders的customerid属性,必须由Order自己去维护,即设置 order.setCustomer(customer);
可以修改Order类代码:
public class Order { private int id; private String orderName; private Customer customer; }
映射文件Order.hbm.xml:
<hibernate-mapping> <class name="test.Order" table="t_order"> <id name="id"> <generator class="native"/> </id> <property name="orderName"/> <many-to-one name="customer" column="customerid"/> </class> </hibernate-mapping>
此时数据库中表的结构不会变化。
再次执行上述代码,发出如下sql语句:
Hibernate: insert into t_customer (name) values (?) Hibernate: insert into t_order (orderName, customerid) values (?, ?) Hibernate: insert into t_order (orderName, customerid) values (?, ?)
发现在保存Order对象时为customerid字段赋值,因为Order对象中拥有Customer属性,对应customerid字段,查看数据库表:
t_customer : t_order:
id | name id | orderName | customerid
1 aaa 1 o1 NULL
2 o2 NULL
发现customerid的值仍为NULL,因为在上述代码中并未设置Order对象的Customer属性值,由于设置了 inverse="true",所以Order对象需要维护关联关系,所以必须进行设置,即order.setCustomer(customer);
修改上述测试代码为:
••• Customer c = new Customer(); Set orders = new HashSet(); Order o1 = new Order(); o1.setOrderName("o1"); o1.setCustomer(c); Order o2 = new Order(); o2.setOrderName("o2"); o2.setCustomer(c); orders.add(o1); orders.add(o2); c.setName("aaa"); c.setOrders(orders); session.save(c);
Hibernate: insert into t_customer (name) values (?) Hibernate: insert into t_order (orderName, customerid) values (?, ?) Hibernate: insert into t_order (orderName, customerid) values (?, ?)
t_customer : t_order:
id | name id | orderName | customerid
1 aaa 1 o1 1
2 o2 1
发现已经设置了customerid的值。
在一对多关联中,在多的一方设置inverse="true",有助于性能的改善。通过上述分析可以发现少了update语句。