Hibernate SQL优化技巧dynamic

发布时间:2024-12-19 14:36

SQL数据库管理:掌握SQL查询和优化 #生活技巧# #工作学习技巧# #编程语言学习路径#

最近正在拜读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>   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 https://www.yuejiaxmz.com/news/view/518857

相关内容

Hibernate SQL优化小技巧使用dynamic
hibernate原生sql注意点
15个常用的sql优化技巧
SQL优化大全:详细总结30个超级实用的SQL优化技巧
SQL Server数据库性能优化(一)之 优化SQL 语句
sql优化的15个小技巧(必知五颗星),面试说出七八个就有了
sql大查询left join拆分优化,去掉临时表
[黑客技术]SQL注入的新技巧
SQL Server 菜鸟教程入门必备指南,轻松掌握数据库操作与查询技巧
Hive 性能优化 9 大技巧

随便看看