熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

如何對Hibernate進行優化的方案

2013-11-23 20:07:52  來源: Java開源技術 
    一批量修改和刪除
   
    在Hibernate 如果需要對任何數據進行修改和刪除操作都需要先執行查詢操作在得到要修改或者刪除的數據後再對該數據進行相應的操作處理在數據量少的情況下采用這種處理方式沒有問題但需要處理大量數據的時候就可能存在以下的問題
   
    占用大量的內存
   
    需要多次執行update/delete語句而每次執行只能處理一條數據
   
    以上兩個問題的出現會嚴重影響系統的性能因此在Hibernate 中引入了用於批量更新或者刪除數據的HQL語句這樣開發人員就可以一次更新或者刪除多條記錄而不用每次都一個一個地修改或者刪除記錄了
   
    如果要刪除所有的User對象(也就是User對象所對應表中的記錄)則可以直接使用下面的HQL語句
   
    delete User
   
    而在執行這個HQL語句時需要調用Query對象的executeUpdate()方法具體的實例如下所示
   
    String HQL=delete User;
   
    Query query=sessioncreateQuery(HQL)
   
    int size=queryexecuteUpdate()
   
    采用這種方式進行數據的修改和刪除時與直接使用JDBC的方式在性能上相差無幾是推薦使用的正確方法
   
    如果不能采用HQL語句進行大量數據的修改也就是說只能使用取出再修改的方式時也會遇到批量插入時的內存溢出問題所以也要采用上面所提供的處理方法來進行類似的處理
   
    二 使用SQL執行批量操作
   
    在進行批量插入修改和刪除操作時直接使用JDBC來執行原生態的SQL語句無疑會獲得最佳的性能這是因為在處理的過程中省略或者簡化了以下處理內容
   
    ● HQL語句到SQL語句的轉換
   
    ● Java對象的初始化
   
    ● Java對象的緩存處理
   
    但是在直接使用JDBC執行SQL語句時有一個最重要的問題就是要處理緩存中的Java對象因為通過這種底層方式對數據的修改將不能通知緩存去進行相應的更新操作以保證緩存中的對象與數據庫中的數據是一致的
   
    三 提升數據庫查詢的性能
   
    數據庫查詢性能的提升也是涉及到開發中的各個階段在開發中選用正確的查詢方法無疑是最基礎也最簡單的
   
    SQL語句的優化
   
    使用正確的SQL語句可以在很大程度上提高系統的查詢性能獲得同樣數據而采用不同方式的SQL語句在性能上的差距可能是十分巨大的
   
    由於Hibernate是對JDBC的封裝SQL語句的產生都是動態由Hibernate自動完成的Hibernate產生SQL語句的方式有兩種一種是通過開發人員編寫的HQL語句來生成另一種是依據開發人員對關聯對象的訪問來自動生成相應的SQL語句
   
    至於使用什麼樣的SQL語句可以獲得更好的性能要依據數據庫的結構以及所要獲取數據的具體情況來進行處理在確定了所要執行的SQL語句後可以通過以下三個方面來影響Hibernate所生成的SQL語句
   
    HQL語句的書寫方法
   
    查詢時所使用的查詢方法
   
    對象關聯時所使用的抓取策略
   
    使用正確的查詢方法
   
    在前面已經介紹過執行數據查詢功能的基本方法有兩種一種是得到單個持久化對象的get()方法和load()方法另一種是Query對象的list()方法和iterator()方法在開發中應該依據不同的情況選用正確的方法
   
    get()方法和load()方法的區別在於對二級緩存的使用上load()方法會使用二級緩存而get()方法在一級緩存沒有找到的情況下會直接查詢數據庫不會去二級緩存中查找在使用中對使用了二級緩存的對象進行查詢時最好使用load()方法以充分利用二級緩存來提高檢索的效率
   
    list()方法和iterator()方法之間的區別可以從以下幾個方面來進行比較
   
    執行的查詢不同
   
    list()方法在執行時是直接運行查詢結果所需要的查詢語句而iterator()方法則是先執行得到對象ID的查詢然後再根據每個ID值去取得所要查詢的對象因此對於list()方式的查詢通常只會執行一個SQL語句而對於iterator()方法的查詢則可能需要執行N+條SQL語句(N為結果集中的記錄數)
   
    iterator()方法只是可能執行N+條數據具體執行SQL語句的數量取決於緩存的情況以及對結果集的訪問情況
   
    緩存的使用
   
    list()方法只能使用二級緩存中的查詢緩存而無法使用二級緩存對單個對象的緩存(但是會把查詢出的對象放入二級緩存中)所以除非重復執行相同的查詢操作否則無法利用緩存的機制來提高查詢的效率
   
    iterator()方法則可以充分利用二級緩存在根據ID檢索對象的時候會首先到緩存中查找只有在找不到的情況下才會執行相應的查詢語句所以緩存中對象的存在與否會影響到SQL語句的執行數量
   
    對於結果集的處理方法不同
   
    list()方法會一次獲得所有的結果集對象而且它會依據查詢的結果初始化所有的結果集對象這在結果集非常大的時候必然會占據非常多的內存甚至會造成內存溢出情況的發生
   
    iterator()方法在執行時不會一次初始化所有的對象而是根據對結果集的訪問情況來初始化對象因此在訪問中可以控制緩存中對象的數量以避免占用過多緩存導致內存溢出情況的發生使用iterator()方法的另外一個好處是如果只需要結果集中的部分記錄那麼沒有被用到的結果對象根本不會被初始化所以對結果集的訪問情況也是調用iterator()方法時執行數據庫SQL語句多少的一個因素
   
    所以在使用Query對象執行數據查詢時應該從以上幾個方面去考慮使用何種方法來執行數據庫的查詢操作
   
    四 使用正確的抓取策略
   
    所謂抓取策略(fetching strategy)是指當應用程序需要利用關聯關系進行對象獲取的時候Hibernate獲取關聯對象的策略抓取策略可以在O/R映射的元數據中聲明也可以在特定的HQL或條件查詢中聲明
   
    Hibernate 定義了以下幾種抓取策略
   
    連接抓取(Join fetching)
   
    連接抓取是指Hibernate在獲得關聯對象時會在SELECT語句中使用外連接的方式來獲得關聯對象
   
    查詢抓取(Select fetching)
   
    查詢抓取是指Hibernate通過另外一條SELECT語句來抓取當前對象的關聯對象的方式這也是通過外鍵的方式來執行數據庫的查詢與連接抓取的區別在於通常情況下這個SELECT語句不是立即執行的而是在訪問到關聯對象的時候才會執行
   
    子查詢抓取(Subselect fetching)
   
    子查詢抓取也是指Hibernate通過另外一條SELECT語句來抓取當前對象的關聯對象的方式與查詢抓取的區別在於它所采用的SELECT語句的方式為子查詢而不是通過外連接
   
    批量抓取(Batch fetching)
   
    批量抓取是對查詢抓取的優化它會依據主鍵或者外鍵的列表來通過單條SELECT語句實現管理對象的批量抓取
   
    以上介紹的是Hibernate 所提供的抓取策略也就是抓取關聯對象的手段為了提升系統的性能在抓取關聯對象的時機上還有以下一些選擇
From:http://tw.wingwit.com/Article/program/Java/ky/201311/27981.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.