最近正在拜读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. 普通用户安装 R 包

    转自 http://bnuzhutao.cn/archives/901 一般 R 语言的书籍上,介绍安装 R 包的方法都是这样的: install.packages("packagename ...

  2. springMVC-InitBinder

    -由@initBinder标识的方法,可以对webDataBinder对象进行初始化.WebDataBinder 的子类,用于完成由表单字段到javaBean属性的绑定 -@InitBinder方法不 ...

  3. Ajax请求接口加密研究(针对网页前端的接口安全加密机制研究)

    通常我们在h5前端调用后台接口时,一般是ajax,那么接口的安全成了一个问题. 这里可以肯定的说,前端调用的接口一定要验证! 然后剖析了微信网页版.京东网页版这些,也都是通过接口的形势绑定数据,所以在 ...

  4. Entity Framework使用Sqlite时的一些配置

    前段时间试着用Entity Framework for Sqlite环境,发现了一些坑坑洼洼,记录一下. 同时试了一下配置多种数据库,包括Sqlite.Sql Server.Sql Server Lo ...

  5. 编写 unix和 windows的 Scala 脚本

    编写 unix和 windows的 Scala 脚本 今天在看<Scala 编程>的时候看到附录了,里面提到了怎么在 unix 和 windows 下面编写 scala 脚本. 之前我也一 ...

  6. 重温布局(display)

    无聊,从新复习了一遍,基础布局,记录一下,避免忘了. 首先说一下 Css文件前缀 Firefox:-moz-box-shadow Safari:-webkit-box-shadow Opera:-o- ...

  7. 使用uWSGI部署django项目

    先说说什么是uWSGI吧,他是实现了WSGI协议.uwsgi.http等协议的一个web服务器,那什么是WSGI呢? WSGI是一种Web服务器网关接口.它是一个Web服务器(如nginx)与应用服务 ...

  8. Hierarchical Softmax

    When predicting over large vocabulary, softmax becomes one of the expensive computation part. There ...

  9. Yocto开发笔记之《Makefile编写》(QQ交流群:519230208)

    开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 =============================== ...

  10. UML活动图与流程图的区别

    http://blog.chinaunix.net/uid-11572501-id-3847592.html UML活动图与流程图的区别 (1).流程图着重描述处理过程,它的主要控制结构是顺序.分支和 ...