最近正在拜讀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能夠性能上的少許提升。