Hibernate SQL优化技巧dynamic-insert="true" dynamic-update="true"

最近正在拜读Hibernate之父大作<Java Persistence with Hibernate>,颇有收获。
在我们熟悉的Hibernate映射文件中也大有乾坤,很多值得我注意的地方。
在Hibernate的映射文件的class tag使用dynamic-insert,dynamic-update,可以优化生成的SQL语句,提高SQL执行效率,最终可以提高系统性能。
如,有一个User类。

  1. public class User {
  2. /** Creates a new instance of User */
  3. public User() {
  4. }
  5. private long id;
  6. private int age;
  7. private String firstname;
  8. private String lastname;
  9. private Set emailAddresses;
  10. //省略getter 和setter方法
  11. }

Hibernate映射文件(User.hbm.xml,省略了文件头声明)定义为:

  1. <hibernate-mapping>
  2. <class name="model.User" table="Users" >
  3. <id name="id" column="ID">
  4. <generator class="native"/>
  5. </id>
  6. <property name="age"/>
  7. <property name="firstname"/>
  8. <property name="lastname"/>
  9. <set name="emailAddresses" table="PERSON_EMAIL_ADDR">
  10. <key column="PERSON_ID"/>
  11. <element type="string" column="EMAIL_ADDR"/>
  12. </set>
  13. </class>
  14. </hibernate-mapping>

我们写一个测试类进行测试UserTest。

  1. public class UserTest extends TestCase {
  2. public UserTest(String testName) {
  3. super(testName);
  4. }
  5. private Session session;
  6. private SessionFactory sessionFactory;
  7. protected void setUp() throws Exception {
  8. sessionFactory=HibernateUtil.getSessionFactory();
  9. session=sessionFactory.openSession();
  10. session.getTransaction().begin();
  11. }
  12. protected void tearDown() throws Exception {
  13. session.getTransaction().commit();
  14. session.close();
  15. }
  16. /**
  17. * Test of getAge method, of class model.User.
  18. */
  19. public void testSaveUser() {
  20. System.out.println("================testSaveUser=================");
  21. User user = new User();
  22. user.setAge(29);
  23. session.save(user);
  24. assertNotNull("id is assigned !",user.getId());
  25. }
  26. public void testUpdateUser() {
  27. System.out.println("================testUpdateUser=================");
  28. User user = new User();
  29. user.setAge(29);
  30. session.save(user);
  31. assertNotNull("id is assigned !",user.getId());
  32. User _user=(User) session.get(User.class, user.getId());
  33. _user.setFirstname("Array");
  34. session.update(_user);
  35. }
  36. }

运行测试后,此时会生成完整的SQL语句(注意将hibernate属性show_sql设置成true)。

  1. ================testSaveUser=================
  2. Hibernate: insert into Users (age, firstname, lastname) values (?, ?, ?)
  3. ================testUpdateUser=================
  4. Hibernate: insert into Users (age, firstname, lastname) values (?, ?, ?)
  5. Hibernate: update Users set age=?, firstname=?, lastname=? where ID=?

如果我们在<class ...>中加上 dynamic-insert="true" dynamic-update="true",变成如下。

  1. <class name="model.User" table="Users" dynamic-insert="true" dynamic-update="true">

再次运行测试类,就会发现生成的SQL中涉及的字段只包含User类中修改的属性所对应的表字段。

  1. ================testSaveUser=================
  2. Hibernate: insert into Users (age) values (?)
  3. ================testUpdateUser=================
  4. Hibernate: insert into Users (age) values (?)
  5. Hibernate: update Users set firstname=? where ID=?

如果一个表的结构很复杂,字段很多的情况下,使用dynamic-insert,dynamic-update能够性能上的少许提升。

-------------------------------------------

Hibernate的映射文件中,class元素中可以定义 
dynamic-update="true|false" 
dynamic-insert="true|false"

dynamic-update (可选, 默认为 false): 指定用于UPDATE 的SQL将会在运行时动态生成,并且只更新那些改变过的字段。

dynamic-insert (可选, 默认为 false): 指定用于INSERT的 SQL 将会在运行时动态生成,并且只包含那些非空值字段。

请注意dynamic-update和dynamic-insert的设置并不会继承到子类, 所以在<subclass>或者<joined-subclass>元素中可能 需要再次设置。

性能问题:SQL update语句是预先生成的,如果加上dynamic的话,每次update的时候需要扫描每个属性的更改,然后生成update,效率会稍微有点影响。 
如果不是有特殊的需求,默认就好了。

如果你一次更新多条记录,hibernate将不能使用executeBatch进行批量更新,这样效率降低很多。同时,在这种情况下,多条sql意味着数据库要做多次sql语句编译。

应否使用: 
具体问题具体分析了,如果一个表字段比较多,并且经常只是更新一条记录的一两个字段,那么动态更新会更有效些。而且生成的SQL语句也容易懂。

转自:http://blog.163.com/ma_yaling/blog/static/245367201051854849268/

相关:

Hibernate update 只更新被修改字段

时间: 2024-10-05 04:59:52

Hibernate SQL优化技巧dynamic-insert="true" dynamic-update="true"的相关文章

SQL优化技巧(Oracle)

SQL优化技巧(1): Where子句中的连接顺序:oracle采用自下而 上的顺序解析where子句,根据这个原理,表 之间的连接必须写在其他where条件之前,那些可以过滤掉大量记录的条件 必须写在where子句的末尾. 例如 低效:select * from report_sale_account e where hsje>5000 and dzxl = '000001' and 25<(select count(*) from report_sale_account where cod

SQL优化技巧

我们开发的大部分软件,其基本业务流程都是:采集数据→将数据存储到数据库中→根据业务需求查询相应数据→对数据进行处理→传给前台展示.对整个流程进行分析,可以发现软件大部分的操作时间消耗都花在了数据库相关的IO操作上.所以对我们的SQL语句进行优化,可以提高软件的响应性能,带来更好的用户体验. 在开始介绍SQL优化技巧之前,先推介一款数据库管理神器Navicat,官网:https://www.navicat.com.cn/whatisnavicat Navicat是一套快速.可靠和全面的数据库管理工

常用的7个SQl优化技巧

作为程序员经常和数据库打交道的时候还是非常频繁的,掌握住一些Sql的优化技巧还是非常有必要的.下面列出一些常用的SQl优化技巧,感兴趣的朋友可以了解一下. 1.注意通配符中Like的使用 以下写法会造成全表的扫描,例如: select id,name from userinfo where name like '%name%' 或者 select id,name from userinfo where name like '%name' 下面的写法执行效率快很多,因为它使用了索引 select

oracle sql优化技巧

数据库方面一直是自己的薄弱项,现在以本文慢慢积累总结oracle sql优化的一些技巧. 1.首先大家很容易想到的一切优化技巧--索引,索引有啥用?索引在表数据量很大时添加索引确实能加快查询速度,通过索引查询能很好地避免全表扫描. 但应该也要注意的时这是在数据量较大的时候.同时数据较小时,反而浪费索引空间.另外,添加索引之后数据的插入,更新反而会变慢,在插入或修改记录 时需要新建索引并排序. 索引创建语句: create [unique] index xxx on A(column 1,colu

13个SQL优化技巧

1 避免无计划的全表扫描<!--?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /--> 如下情况进行全表扫描: - 该表无索引 - 对返回的行无人和限制条件(无Where子句) - 对于索引主列(索引的第一列)无限制条件 - 对索引主列的条件含在表达式中 - 对索引主列的限制条件是is (not) null或!= - 对索引主列的限制条件是like操作且值是一个bind va

SQL优化技巧-批处理替代游标

通过MSSQL中的用户自定义表类型可以快速将需要处理的数据存储起来,生成新的临时表(这里使用变量表),然后根据表中字段进行批处理替代游标. 用户自定义表类型 0 --创建用户自定义表类型 1 Create Type [dbo].[type_XXXTable] As Table( 2 [Item1] [Varchar](255) Null, 3 [Item2] [Varchar](255) Null, 4 [Item3] [Varchar](255) Null, 5 [Item4] [Varcha

Ms sql server sql优化技巧

SET STATISTICS PROFILE ON SET STATISTICS IO ON SET STATISTICS TIME ON SELECT * FROM userinfo WHERE Name IS NOT NULL AND Name = '刘' SELECT * FROM userinfo WHERE Name = '刘' SET STATISTICS PROFILE OFF SET STATISTICS IO OFF SET STATISTICS TIME OFF

SQL语句常用优化技巧(一)

要提高SQL语句的执行效率,最常见的方法就是建立索引,以及尽量避免全表扫描.给大家整理一些常见的SQL优化技巧,避免全表扫描.一个简单的优化,也许能让你的SQL执行效率提高几倍,甚至几十倍. 1.避免在where子句中使用 is null 或 is not null 对字段进行判断. 如: select id from table where name is null 在这个查询中,就算我们为 name 字段设置了索引,查询分析器也不会使用,因此查询效率底下.为了避免这样的查询,在数据库设计的时

一个mysql优化技巧的误区

关于sql优化技巧,大家可能见过N个版本,尤其容易博得初中级程序员的眼球.倘若没有一点分析实践能力,直接将其拿来当作圣经记在心中并实践于工作中,那你极有可能被掉坑.轻则代码运行转圈圈无响应,重则导致项目瘫痪造成经济损失. 废话不多说,直接上图. 上面这条技巧粗略看一眼好像也没有什么问题.可事实是这样的吗? 结论当然是否定的.且看实例分析: CREATE TABLE `t_auxiliary_info` (   `id` int(11) unsigned NOT NULL AUTO_INCREME