Hibernate SQL优化技巧dynamic-insert="true" dynamic-update="true"
最近正在拜读Hibernate之父大作<Java Persistence with Hibernate>,颇有收获。
在我们熟悉的Hibernate映射文件中也大有乾坤,很多值得我注意的地方。
在Hibernate的映射文件的class tag使用dynamic-insert,dynamic-update,可以优化生成的SQL语句,提高SQL执行效率,最终可以提高系统性能。
如,有一个User类。
- public class User {
- /** Creates a new instance of User */
- public User() {
- }
- private long id;
- private int age;
- private String firstname;
- private String lastname;
- private Set emailAddresses;
- //省略getter 和setter方法
- }
Hibernate映射文件(User.hbm.xml,省略了文件头声明)定义为:
- <hibernate-mapping>
- <class name="model.User" table="Users" >
- <id name="id" column="ID">
- <generator class="native"/>
- </id>
- <property name="age"/>
- <property name="firstname"/>
- <property name="lastname"/>
- <set name="emailAddresses" table="PERSON_EMAIL_ADDR">
- <key column="PERSON_ID"/>
- <element type="string" column="EMAIL_ADDR"/>
- </set>
- </class>
- </hibernate-mapping>
我们写一个测试类进行测试UserTest。
- public class UserTest extends TestCase {
- public UserTest(String testName) {
- super(testName);
- }
- private Session session;
- private SessionFactory sessionFactory;
- protected void setUp() throws Exception {
- sessionFactory=HibernateUtil.getSessionFactory();
- session=sessionFactory.openSession();
- session.getTransaction().begin();
- }
- protected void tearDown() throws Exception {
- session.getTransaction().commit();
- session.close();
- }
- /**
- * Test of getAge method, of class model.User.
- */
- public void testSaveUser() {
- System.out.println("================testSaveUser=================");
- User user = new User();
- user.setAge(29);
- session.save(user);
- assertNotNull("id is assigned !",user.getId());
- }
- public void testUpdateUser() {
- System.out.println("================testUpdateUser=================");
- User user = new User();
- user.setAge(29);
- session.save(user);
- assertNotNull("id is assigned !",user.getId());
- User _user=(User) session.get(User.class, user.getId());
- _user.setFirstname("Array");
- session.update(_user);
- }
- }
运行测试后,此时会生成完整的SQL语句(注意将hibernate属性show_sql设置成true)。
- ================testSaveUser=================
- Hibernate: insert into Users (age, firstname, lastname) values (?, ?, ?)
- ================testUpdateUser=================
- Hibernate: insert into Users (age, firstname, lastname) values (?, ?, ?)
- Hibernate: update Users set age=?, firstname=?, lastname=? where ID=?
如果我们在<class ...>中加上 dynamic-insert="true" dynamic-update="true",变成如下。
- <class name="model.User" table="Users" dynamic-insert="true" dynamic-update="true">
再次运行测试类,就会发现生成的SQL中涉及的字段只包含User类中修改的属性所对应的表字段。
- ================testSaveUser=================
- Hibernate: insert into Users (age) values (?)
- ================testUpdateUser=================
- Hibernate: insert into Users (age) values (?)
- 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"的更多相关文章
- SQL优化技巧
我们开发的大部分软件,其基本业务流程都是:采集数据→将数据存储到数据库中→根据业务需求查询相应数据→对数据进行处理→传给前台展示.对整个流程进行分析,可以发现软件大部分的操作时间消耗都花在了数据库相关 ...
- 常用的7个SQl优化技巧
作为程序员经常和数据库打交道的时候还是非常频繁的,掌握住一些Sql的优化技巧还是非常有必要的.下面列出一些常用的SQl优化技巧,感兴趣的朋友可以了解一下. 1.注意通配符中Like的使用 以下写法会造 ...
- 19 个让 MySQL 效率提高 3 倍的 SQL 优化技巧
优化成本: 硬件>系统配置>数据库表结构>SQL及索引 优化效果: 硬件<系统配置<数据库表结构<SQL及索引 本文我们就来谈谈 MySQL 中常用的 SQL 优化 ...
- 数据库的规范和SQL优化技巧总结
现总结工作与学习中关于数据库的规范设计与优化技巧 1.规范背景与目的 MySQL数据库与 Oracle. SQL Server 等数据库相比,有其内核上的优势与劣势.我们在使用MySQL数据库的时候需 ...
- SQL优化技巧--远程连接对象引起的CTE性能问题
背景 最近SSIS的开发过程中遇到几个问题.其中使用CTE时,遇到一个远程连接对象,结果导致严重的性能问题,为了应急我就修改了代码. 之前我写了一篇介绍CTE的随笔包含了CTE的用法等: http:/ ...
- 数据库查询优化-20条必备sql优化技巧
0.序言 本文我们来谈谈项目中常用的 20 条 MySQL 优化方法,效率至少提高 3倍! 具体如下: 1.使⽤ EXPLAIN 分析 SQL 语句是否合理 使⽤ EXPLAIN 判断 SQL 语句是 ...
- 13个SQL优化技巧
避免无计划的全表扫描<!--?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" ...
- MySql Sql 优化技巧分享
有天发现一个带inner join的sql 执行速度虽然不是很慢(0.1-0.2),但是没有达到理想速度.两个表关联,且关联的字段都是主键,查询的字段是唯一索引. sql如下: SELECT p_it ...
- 一个MySql Sql 优化技巧分享
有天发现一个带inner join的sql 执行速度虽然不是很慢(0.1-0.2),但是没有达到理想速度.两个表关联,且关联的字段都是主键,查询的字段是唯一索引. sql如下: SELECT p_it ...
随机推荐
- 如何更改IP地址的映射名字
windows系统下: 在C:\Windows\System32\drivers\etc\hosts里面添加你想对应的域名 如192.168.230.134 weekend110 注意:这要有管理员权 ...
- 【BZOJ-3144】切糕 最小割-最大流
3144: [Hnoi2013]切糕 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1261 Solved: 700[Submit][Status] ...
- VS生成事件宏$(TargetPath) 一直为空
在接手以前的项目的时候,遇见一个很奇怪的问题,我在一个项目的类库里面,使用了生成实现,如下: copy /Y $(TargetPath) $(SolutionDir)..\ copy /Y $(Tar ...
- Java replace & replaceAll
Java字符串中需要对一些字符进行替换,用到最多的是replace和replaceAll两个方法.这两个方法在使用的时候需要注意: replace: public String replace (Ch ...
- C#关闭窗口代码
if (MessageBox.Show("请您确认是否退出(Y/N)", "系统提示", MessageBoxButtons.YesNo, MessageBox ...
- CentOS 下安装
2016年12月5日15:25:58 ----------------------------------- 通常情况下在centos下安装软件就用yum. 关键是,使用yum你要知道安装包的名字是什 ...
- IOS - Create Push Segue Animation Without UINavigationController
APPLE提供了三种storyboard segue的方式:push,modal,custom . push segue是系统预定义的跳转方式, 为了使其能正常工作,我们还必须加载UINavigati ...
- POJ 3678 Katu Puzzle(强连通 法)
题目链接 题意:给出a, b, c 和操作类型 (与或异或),问是否满足所有的式子 主要是建图: 对于 and , c == 1: 说明 a 和 b都是1,那么 0 就不能取, a' -> a ...
- 如何在maven中添加jar包
Maven 中央仓库地址: 1. http://www.sonatype.org/nexus/ 2. http://mvnrepository.com/ (本人推荐仓库) 3. http://repo ...
- python--文件删除、判断目录存在、字符串替换
昨晚笔试了金山WPS的测试开发卷,做个笔记(但不是答案,只是我的想法),关于文件和字符串的处理正在写入与完善至上一篇的博客中,现在题目如下: 1.使用脚本语言删除E:\abc目录下的所有文件: 利用o ...