最近正在拜读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 只更新被修改字段

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

  1. SQL优化技巧

    我们开发的大部分软件,其基本业务流程都是:采集数据→将数据存储到数据库中→根据业务需求查询相应数据→对数据进行处理→传给前台展示.对整个流程进行分析,可以发现软件大部分的操作时间消耗都花在了数据库相关 ...

  2. 常用的7个SQl优化技巧

    作为程序员经常和数据库打交道的时候还是非常频繁的,掌握住一些Sql的优化技巧还是非常有必要的.下面列出一些常用的SQl优化技巧,感兴趣的朋友可以了解一下. 1.注意通配符中Like的使用 以下写法会造 ...

  3. 19 个让 MySQL 效率提高 3 倍的 SQL 优化技巧

    优化成本: 硬件>系统配置>数据库表结构>SQL及索引 优化效果: 硬件<系统配置<数据库表结构<SQL及索引 本文我们就来谈谈 MySQL 中常用的 SQL 优化 ...

  4. 数据库的规范和SQL优化技巧总结

    现总结工作与学习中关于数据库的规范设计与优化技巧 1.规范背景与目的 MySQL数据库与 Oracle. SQL Server 等数据库相比,有其内核上的优势与劣势.我们在使用MySQL数据库的时候需 ...

  5. SQL优化技巧--远程连接对象引起的CTE性能问题

    背景 最近SSIS的开发过程中遇到几个问题.其中使用CTE时,遇到一个远程连接对象,结果导致严重的性能问题,为了应急我就修改了代码. 之前我写了一篇介绍CTE的随笔包含了CTE的用法等: http:/ ...

  6. 数据库查询优化-20条必备sql优化技巧

    0.序言 本文我们来谈谈项目中常用的 20 条 MySQL 优化方法,效率至少提高 3倍! 具体如下: 1.使⽤ EXPLAIN 分析 SQL 语句是否合理 使⽤ EXPLAIN 判断 SQL 语句是 ...

  7. 13个SQL优化技巧

    避免无计划的全表扫描<!--?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" ...

  8. MySql Sql 优化技巧分享

    有天发现一个带inner join的sql 执行速度虽然不是很慢(0.1-0.2),但是没有达到理想速度.两个表关联,且关联的字段都是主键,查询的字段是唯一索引. sql如下: SELECT p_it ...

  9. 一个MySql Sql 优化技巧分享

    有天发现一个带inner join的sql 执行速度虽然不是很慢(0.1-0.2),但是没有达到理想速度.两个表关联,且关联的字段都是主键,查询的字段是唯一索引. sql如下: SELECT p_it ...

随机推荐

  1. asp.net使用signalr实现集群集群下面的消息推送

    1.选用Signalr的原因 Signalr内部给我们做了很多封装.当服务器或者浏览器不支持websoket协议的时候就使用长连接方式  不支持长连接再选用轮询的方式获取消息 websoket:与服务 ...

  2. jdbc/ojdbc连oracle的三种方式(转)

    文章转自:http://blog.itpub.net/22664653/viewspace-1383092/ 前言  本文是一篇学习笔记,学习如何通过java jdbc /ojdbc 连接oracle ...

  3. PHP的几个常用加密函数

    在php的开发过程中,常常需要对部分数据(如用户密码)进行加密 一.加密类型: 1.单向散列加密 就是把任意长度的信息进行散列计算,得到固定长度的输出,这个散列计算过程是单向的,即不能对固定长度的输出 ...

  4. Python 循环判断和数据类型

    循环和判断 1.if 形式 if condition_1: statement_block_1 elif condition_2: statement_block_2 else: statement_ ...

  5. python zip()

    >>> help(zip) Help on built-in function zip in module __builtin__: zip(...) zip(seq1 [, seq ...

  6. 用DOS命令打开IE浏览器、我的文档等等

    用DOS命令打开IE浏览器 在“start”-运行中直接输入网址就可以了.如输入百度: http://www.baidu.com Command:[ start  http://www.baidu.c ...

  7. 网络存储(二)之ISCSI原理

    组成 一个简单ISCSI系统大致由以下部分构成 ISCSI Initiator 或者 ISCSI HBA ISCSI Target 以太网交换机 一台或者多台服务器 结构图如下: iscsi服务器用来 ...

  8. String.format()用法

    package junit.test;   import java.util.Date; import java.util.Locale;   import org.junit.Test;   pub ...

  9. python click module for command line interface

    Click Module(一)                                                  ----xiaojikuaipao The following mat ...

  10. gnuplot使用2

    设置图中连线的颜色.宽度.连线样式等 set style line 每个显示终端都有默认的线类型和点类型集合,可以通过在命令行输入: test查看,如下图显示了在wxt终端模式下默认的线的集合和点的集 ...