双向关联产生多余的SQL语句
/** ????* 添加一个订单到id为6的客户中 ????*/ ???@Test ???public void fun1(){ ????????Session session = HibernateUtils.getSession(); ????????session.getTransaction().begin(); ?????????????????try { ???????????Customer cst = session.get(Customer.class, 6); ?????????????????????????Order od = new Order(); ????????????od.setDetail_id(UUID.randomUUID().toString()); ?????????????????????????cst.getOds().add(od); ???????} catch (Exception e) { ???????????session.getTransaction().rollback(); ???????????// TODO Auto-generated catch block ???????????e.printStackTrace(); ???????} ??????????????????????????session.getTransaction().commit(); ???}
这是Hibernate生成的语句:
Hibernate:
select
customer0_.cust_id as cust_id1_0_0_,
customer0_.cust_name as cust_nam2_0_0_,
customer0_.cust_gender as cust_gen3_0_0_,
customer0_.cust_age as cust_age4_0_0_,
customer0_.cust_phone as cust_pho5_0_0_
from
customera customer0_
where
customer0_.cust_id=?
Hibernate:
select
ods0_.cust_order_id as cust_ord3_1_0_,
ods0_.order_id as order_id1_1_0_,
ods0_.order_id as order_id1_1_1_,
ods0_.detail_id as detail_i2_1_1_,
ods0_.cust_order_id as cust_ord3_1_1_
from
ordersa ods0_
where
ods0_.cust_order_id=?
Hibernate:
insert
into
ordersa
(detail_id, cust_order_id, order_id)
values
(?, ?, ?)
Hibernate:
update
ordersa
set
cust_order_id=?
where
order_id=?
很容易发现,对于外键属性,cust_order_id,hibernate进行了两次维护,即进行了两次更新,这明显对性能有影响。如何减少这类SQL语句的生成,就得用到inverse了。
如何会有两次维护外键的语句生成?
因为双向维护关系,而且持久态对象可以自动更新数据库,更新客户的时候会修改一次外键,更新订单的时候同样也会修改一次外键。这样就会产生了多余的SQL。
解决方法:
只需要将一方放弃外键维护权即可。也就是说关系不是双方维护的,只需要交给某一方去维护就可以了。通常我们都是交给多的一方去维护的,为什么呢?因为多的一方才是维护关系的最好的地方,举个例子:一个老师对应多个学生,一个学生对应一个老师,这是典型的一对多。那么一个老师如果记住了所有学生的名字是很难得,但如果让每个学生记住老师的名字应该不难。所以在一对多中,一的一方都会放弃外键的维护权(关系的维护)。这个时候如果想让一的一方放弃外键的维护权只需要
在一的一方中有如下配置(customer.hbm.xml)
<!-- 配置一对多属性 --> ???????<set name="ods" cascade="save-update" inverse="true"> ???????????<key column="cust_order_id"></key> ???????????<one-to-many class="Order"/> ???????</set>
再次执行上述java的添加订单的代码
Hibernate:
select
customer0_.cust_id as cust_id1_0_0_,
customer0_.cust_name as cust_nam2_0_0_,
customer0_.cust_gender as cust_gen3_0_0_,
customer0_.cust_age as cust_age4_0_0_,
customer0_.cust_phone as cust_pho5_0_0_
from
customera customer0_
where
customer0_.cust_id=?
Hibernate:
select
ods0_.cust_order_id as cust_ord3_1_0_,
ods0_.order_id as order_id1_1_0_,
ods0_.order_id as order_id1_1_1_,
ods0_.detail_id as detail_i2_1_1_,
ods0_.cust_order_id as cust_ord3_1_1_
from
ordersa ods0_
where
ods0_.cust_order_id=?
Hibernate:
insert
into
ordersa
(detail_id, cust_order_id, order_id)
values
(?, ?, ?)
明显SQL少了一句。
inverse的默认值是false,代表不放弃外键维护权,配置值为true,代表放弃了外键的维护权。(让对方来维护)
Hibernate入门(十)inverse
原文地址:https://www.cnblogs.com/deepSleeping/p/9979245.html