Hibernate SQL優(yōu)化小技巧
Hibernate SQL優(yōu)化小技巧使用dynamic-insert="true" dynamic-update="true"
最近正在拜讀Hibernate之父大作《Java Persistence with Hibernate》,頗有收獲。在我們熟悉的Hibernate映射文件中也大有乾坤,很多值得我注意的地方。
在Hibernate的映射文件的class tag使用dynamic-insert,dynamic-update,可以優(yōu)化生成的Hibernate SQL語句,提高Hibernate SQL執(zhí)行效率,最終可以提高系統(tǒng)性能。
如,有一個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>
我們寫一個測試類進(jìn)行測試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);
- }
- }
運行測試后,此時會生成完整的Hibernate SQL語句(注意將hibernate屬性show_sql設(shè)置成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">
再次運行測試類,就會發(fā)現(xiàn)生成的Hibernate SQL中涉及的字段只包含User類中修改的屬性所對應(yīng)的表字段。
- ================testSaveUser=================
- Hibernate: insert into Users (age) values (?)
- ================testUpdateUser=================
- Hibernate: insert into Users (age) values (?)
- Hibernate: update Users set firstname=? where ID=?
如果一個表的結(jié)構(gòu)很復(fù)雜,字段很多的情況下,使用dynamic-insert,dynamic-update能夠性能上的少許提升。
【編輯推薦】