代码优化:Hibernate中的动态更新 dynamic-update

时间:2022-09-08 16:13:13

一、前言

在如下编码中

Session session = HibernateSessionFactory.getSession();
Transaction tx = null;
try {
tx = sessoin.beginTransaction();
Emp e = (Emp)session.load(Emp.class, (short)7940);
e.setEname("bbb");
e.setEname("aaa");
tx.commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
if(tx != null){
tx.rollback();
System.out.println("rollback");
}
}

虽然没有update字样,但是控制台显示的确进行了update的处理

Hibernate: 
update
EMP
set
ENAME=?,
JOB=?,
MGR=?,
HIREDATE=?,
SAL=?,
COMM=?,
DEPTNO=?
where
EMPNO=?

追其缘由,就是通过load返回了一个临时对象,
该临时对象是数据库对应数据的快照,
再进行对临时对象的修改,
之后的commit会对缓存中的临时对象去和数据库中的数据(也就是刚才的快照,这是Hibernate)进行比较,
不同则进行数据同步处理,调用update方法

这种机制的确很智能,对代码新人很有包容性,
但我们也发现了Hibernate更新了所有的数据
作为一个合格的程序员,不能仅满足于实现需求而已,
仍需要考虑到效率方面的问题,
我只需要更改我更改过的数据就好了
因此动态更新应运而生

二、动态更新

什么是动态更新?
粗略的讲,就是只更新修改的参数,其余不变,从而提高更新的效率

具体步骤:
1.在对应类的映射文件中填写如下参数:

<class name="po.Emp" table="EMP" dynamic-update="true">

(tip:dynamic-update的默认值是false)
2.再进行事务中的更新操作

Session session = HibernateSessionFactory.getSession();
tx = session.beginTransaction();
Emp e = (Emp)session.load(Emp.class, (short)7940);
e.setEname("aaa");
tx.commit();

3.的确仅对更新的字段进行更新,控制台中提示如下

Hibernate: 
update
EMP
set
ENAME=?
where
EMPNO=?

总结:虽然Hibernate内部机制会在事务中进行临时对象和数据库中数据进行同步处理,虽然智能,但是智能的背后潜藏着效率上的落后;相对比再来看动态更新,从之前的更新全部到动态更新的只更新修改的字段,动态更新使更新效率有了质的飞跃。

还是那句话,虽然框架中有很多智能的、包容的、可容错的机制,但是为了提高效率,还是应该找到适合项目的替代方案