概括Hibernate批量處理
Hibernate有很多值得學(xué)習(xí)的地方,這里我們主要介紹Hibernate批量處理,包括介紹應(yīng)用程序也必須繞過Hibernate API,直接通過JDBC API來調(diào)用存儲過程等方面。
Hibernate批量處理其實從性能上考慮,它是很不可取的,浪費了很大的內(nèi)存。從它的機制上講,Hibernate它是先把符合條件的數(shù)據(jù)查出來,放到內(nèi)存當(dāng)中,然后再進(jìn)行操作。實際使用下來性能非常不理想,在筆者的實際使用中采用下面的第三種優(yōu)化方案的數(shù)據(jù)是:100000條數(shù)據(jù)插入數(shù)據(jù)庫,主流臺式機的配置,需要約30分鐘,呵呵,暈倒。
總結(jié)下來有三種來處理以解決性能問題:
1:繞過Hibernate API ,直接通過 JDBC API 來做,這個方法性能上是比較好的。也是最快的。
2:運用存儲過程。
3:還是用Hibernate API 來進(jìn)行常規(guī)的批量處理,可以也有變,變就變在,我們可以在查找出一定的量的時候,及時的將這些數(shù)據(jù)做完操作就
刪掉,session.flush();session.evict(XX對象集); 這樣也可以挽救一點性能損失。這個“一定的量”要就要根據(jù)實際情況做定量參考了。一般為30-60左右,但效果仍然不理想。
1:繞過Hibernate API ,直接通過 JDBC API 來做,這個方法性能上是比較好的,也是最快的。(實例為 更新操作)
- Transaction tx=session.beginTransaction();
- //注意用的是hibernate事務(wù)處理邊界
- Connection conn=session.connection();
- PreparedStatement stmt=conn.preparedStatement
("update CUSTOMER as C set C.sarlary=c.sarlary+1 where c.sarlary>1000");- stmt.excuteUpdate();
- tx.commit();
- //注意用的是hibernate事務(wù)處理邊界
這小程序中,采用的是直接調(diào)用JDBC 的API 來訪問數(shù)據(jù)庫,效率很高。避免了Hibernate 先查詢出來加載到內(nèi)存,再進(jìn)行操作引發(fā)的性能問題。
2:運用存儲過程。但這種方式考慮到易植和程序部署的方便性,不建議使用。(實例為 更新操作)
如果底層數(shù)據(jù)庫(如Oracle)支持存儲過程,也可以通過存儲過程來執(zhí)行批量更新。存儲過程直接在數(shù)據(jù)庫中運行,速度更加快。在Oracle數(shù)
據(jù)庫中可以定義一個名為batchUpdateCustomer()的存儲過程,代碼如下:
- create or replace procedure batchUpdateCustomer(p_age in number)
as begin update CUSTOMERS set AGEAGE=AGE+1 where AGE>p_age;- end;
以上存儲過程有一個參數(shù)p_age,代表客戶的年齡,應(yīng)用程序可按照以下方式調(diào)用存儲過程:
- tx = session.beginTransaction();
- Connection con=session.connection();
- String procedure = "{call batchUpdateCustomer(?) }";
- CallableStatement cstmt = con.prepareCall(procedure);
- cstmt.setInt(1,0);
- //把年齡參數(shù)設(shè)為0
- cstmt.executeUpdate();
- tx.commit();
從上面程序看出,應(yīng)用程序也必須繞過Hibernate API,直接通過JDBC API來調(diào)用存儲過程。以上介紹Hibernate批量處理。
【編輯推薦】