`

[转]Hibernate的dynamic-insert dynamic-update和select-before-update

阅读更多
http://blog.csdn.net/hsuxu/article/details/8108326

Hibernate在初始化的时候,默认按照配置为表预定义insert,delete,update,select(by id)的SQL语句放在session中,其中insert,update,select操作都是对表的所有字段操作.如果在一个表有很多字段的时候,在做初次inser的时候有比较多的字段为空值,或者经常update某少部分字段,应该在配置文件的<class>元素上将dynamic-insert和dynamic-update设置为true.其默认值都为false.

如有这样一张表:create table hbtest(id int,val1 varchar2(100),val2 varchar2(100));

1,在 dynamic-insert没有设置的时候
<class name="com.test.hb.dynamicupdate.Hbtest" table="HBTEST">
            Hbtest tbo = new Hbtest();
            tbo.setId(new Integer(2));
            tbo.setVal1("val1");
            sessionFactory.getCurrentSession().save(tbo);

某些字段为空做insert,hibernate会用全字段的insert sql语句,如下:

insert into HBTEST(VAL1, VAL2,ID) values(?, ?,?)

2,将dynamic-insert设置为true,同样的保存,hibernate会动态生成SQL语句,没有值的字段不会出现在insert语句中.

<class name="com.test.hb.dynamicupdate.Hbtest" dynamic-insert="true" table="HBTEST">
insert into HBTEST(VAL1, ID) values(?, ?)

3,在 dynamic-update没有设置的时候

            Hbtest tbo = (Hbtest) sessionFactory.getCurrentSession().load(Hbtest.class,new Integer(1));           
            tbo.setVal1("valXX");           
            tx.commit();

只更新部分字段,hibernate仍然对所有字段做更新:
update HBTEST set VAL1=?,VAL2=? where ID=?

4,同样的操作如果把设置为true的话,sql语句只包含更新的字段:update HBTEST set VAL1=? where ID=?

<class name="com.test.hb.dynamicupdate.Hbtest" dynamic-insert="true" dynamic-update="true" table="HBTEST">

5,Hibernate这种动态SQLupdate的特性是利用在对象从数据库加载到hibernate session的时候保存了一份快照,做更新的时候与这个快照做比较,只更新改动过的值.

所以下面这种情况就会用全部字段进行更新:,不设值的字段会被更新成null.

            Hbtest tbo = new Hbtest();
            tbo.setId(new Integer(1));
            tbo.setVal1("val1ZZZ");
            sessionFactory.getCurrentSession().update(tbo);   
这种情况应该利用Hibernate提供的对SQL的支持,用SQL做更新操作.


动态update对性能有一个重大的影响,就是打开了以后,不同的对象的sql语句会不一样,如果你一次更新多条记录,hibernate将不能使用 executeBatch进行批量更新,这样效率降低很多。同时,在这种情况下,多条sql意味着数据库要做多次sql语句编译。
hibernate默认关闭了动态更新我认为是有道理的,通常情况下动态更新还是不要打开的好。

在你的情况下,是否应该打开,需要具体问题具体分析了。如果一个表字段比较多,并且经常只是更新一条记录的一两个字段,那么动态更新会更有效


select-before-update (可选,默认值为false): 指定Hibernate除非确定对象的确被修改了,不会执行SQL UPDATE操作。在特定场合(实际上,只会发生在一个临时对象关联到一个新的session中去,执行update()的时候),这说明Hibernate会在UPDATE之前执行一次额外的SQL SELECT操作,来决定是否应该进行UPDATE。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics