1. 程式人生 > >程式碼優化:Hibernate中的動態更新 dynamic-update

程式碼優化:Hibernate中的動態更新 dynamic-update

一、前言

在如下編碼中

Session session = HibernateSessionFactory.getSession();
Transaction tx = null;
        try {
            tx = sessoin.beginTransaction();
            Emp e = (Emp)session.load(Emp.class, (short)7940);
            e.setEname("bbb");          
            e.setEname("aaa");
            tx.commit
(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); if(tx != null){ tx.rollback(); System.out.println("rollback"); } }

雖然沒有update字樣,但是控制檯顯示的確進行了update的處理

Hibernate: 
    update
EMP set ENAME=?, JOB=?, MGR=?, HIREDATE=?, SAL=?, COMM=?, DEPTNO=? where EMPNO=?

追其緣由,就是通過load返回了一個臨時物件,
該臨時物件是資料庫對應資料的快照,
再進行對臨時物件的修改,
之後的commit會對快取中的臨時物件去和資料庫中的資料(也就是剛才的快照,這是Hibernate)進行比較,
不同則進行資料同步處理,呼叫update方法

這種機制的確很智慧,對程式碼新人很有包容性,
但我們也發現了Hibernate更新了所有的資料
作為一個合格的程式設計師,不能僅滿足於實現需求而已,
仍需要考慮到效率方面的問題,
我只需要更改我更改過的資料就好了
因此動態更新應運而生

二、動態更新

什麼是動態更新?
粗略的講,就是隻更新修改的引數,其餘不變,從而提高更新的效率

具體步驟:
1.在對應類的對映檔案中填寫如下引數:

<class name="po.Emp" table="EMP" dynamic-update="true">

(tip:dynamic-update的預設值是false)
2.再進行事務中的更新操作

Session session = HibernateSessionFactory.getSession();
tx = session.beginTransaction();
Emp e = (Emp)session.load(Emp.class, (short)7940);
e.setEname("aaa");
tx.commit();

3.的確僅對更新的欄位進行更新,控制檯中提示如下

Hibernate: 
    update
        EMP 
    set
        ENAME=? 
    where
        EMPNO=?

總結:雖然Hibernate內部機制會在事務中進行臨時物件和資料庫中資料進行同步處理,雖然智慧,但是智慧的背後潛藏著效率上的落後;相對比再來看動態更新,從之前的更新全部到動態更新的只更新修改的欄位,動態更新使更新效率有了質的飛躍。

還是那句話,雖然框架中有很多智慧的、包容的、可容錯的機制,但是為了提高效率,還是應該找到適合專案的替代方案