Hibernate獲取資料方式與快取使用

2021-04-27 06:33:23 字數 2594 閱讀 2031

hibernate獲取資料的方式有不同的幾種,其與快取結合使用的效果也不盡相同,而hibernate中具體怎麼使用快取其實是我們很關心的乙個問題,直接涉及到效能方面。

快取在hibernate中主要有三個方面:一級快取、二級快取和查詢快取;一級快取在hibernate中對應的即為session範圍的快取,也就是當 session關閉時快取即被清除,一級快取在hibernate中是不可配置的部分;二級快取在hibernate中對應的即為 sessionfactory範圍的快取,通常來講sessionfactory的生命週期和應用的生命週期相同,所以可以看成是程序快取或集群快取,二級快取在hibernate中是可以配置的,可以通過class-cache配置類粒度級別的快取(class-cache在class中資料發生任何變化的情況下自動更新),同時也可通過collection-cache配置集合粒度級別的快取(collection-cache僅在 collection中增加了元素或者刪除了元素的情況下才自動更新,也就是當collection中元素發生值的變化的情況下它是不會自動更新的),快取自然會帶來併發的訪問問題,這個時候相應的就要根據應用來設定快取所採用的事務隔離級別,和資料庫的事務隔離級別概念基本一樣,沒什麼多介紹的, ^_^;查詢快取在hibernate同樣是可配置的,預設是關閉的,可以通過設定cache.use_ query_cache為true來開啟查詢快取。根據快取的通常實現策略,我們可以來理解hibernate的這三種快取,快取的實現通過是通過key/value的map方式來實現,在 hibernate的一級、二級和查詢快取也同樣如此,一級、二級快取使用的key均為po的主鍵id,value即為po例項物件,查詢快取使用的則為查詢的條件、查詢的引數、查詢的頁數,value有兩種情況,如果採用的是select po.property這樣的方式那麼value為整個結果集,如採用的是from這樣的方式那麼value為獲取的結果集中各po物件的主鍵id,這樣的作用很明顯,節省記憶體,^_^

簡單介紹完hibernate的快取後,再結合hibernate的獲取資料方式來說明快取的具體使用方式,在hibernate中獲取資料常用的方式主要有四種:session.load、session.get、query.list、query.iterator。

1、session.load

在執行session.load時,hibernate首先從當前session的一級快取中獲取id對應的值,在獲取不到的情況下,將根據該物件是否配置了二級快取來做相應的處理,如配置了二級快取,則從二級快取中獲取id對應的值,如仍然獲取不到則還需要根據是否配置了延遲載入來決定如何執行,如未配置延遲載入則從資料庫中直接獲取,在從資料庫獲取到資料的情況下,hibernate會相應的填充一級快取和二級快取,如配置了延遲載入則直接返回乙個**類,只有在觸發**類的呼叫時才進行資料庫查詢的操作。

在這樣的情況下我們就可以看到,在session一直開啟的情況下,要注意在適當的時候對一級快取進行重新整理操作,通常是在該物件具有單向關聯維護的時候,在hibernate中可以使用象session.clear、session.evict的方式來強制重新整理一級快取。

二級快取則在資料發生任何變化(新增、更新、刪除)的情況下都會自動的被更新。

2、session.get

在執行session.get時,和session.load不同的就是在當從快取中獲取不到時,直接從資料庫中獲取id對應的值。

3、query.list

在執行query.list時,hibernate的做法是首先檢查是否配置了查詢快取,如配置了則從查詢快取中查詢key為查詢語句+查詢引數+分頁條件的值,如獲取不到則從資料庫中進行獲取,從資料庫獲取到後hibernate將會相應的填充一級、二級和查詢快取,如獲取到的為直接的結果集,則直接返回,如獲取到的為一堆id的值,則再根據id獲取相應的值(session.load),最後形成結果集返回,可以看到,在這樣的情況下,list也是有可能造成n次的查詢的。

查詢快取在資料發生任何變化的情況下都會被自動的清空。

4、query.iterator

在執行query.iterator時,和query.list的不同的在於從資料庫獲取的處理上,query.iterator向資料庫發起的是 select id from這樣的語句,也就是它是先獲取符合查詢條件的id,之後在進行iterator.next呼叫時才再次發起session.load的呼叫獲取實際的資料。

可見,在擁有二級快取並且查詢引數多變的情況下,query.iterator會比query.list更為高效。

這四種獲取資料的方式都各有適用的場合,要根據實際情況做相應的決定,^_^,最好的方式無疑就是開啟show_sql選項看看執行的情況來做分析,系統結構上只用保證這種調整是容易實現的就好了,在cache這個方面的調整自然是非常的容易,只需要調整配置檔案裡的設定,而查詢的方式則可對外部進行遮蔽,這樣要根據實際情況調整也非常容易。

推薦三篇關於hibernate快取機制介紹的文章:

Hibernate資料載入方式

hibernate資料載入方式 1 即時載入 immediate loading 當實體載入完成後,立即載入與實體相關聯的資料。即當實體載入完成後,hibernate自動立即讀取與實體相關聯的資料,並且填充到實體對應的屬性中。這種載入通常有多條select語句,即select實體資料後,同時sele...

Hibernate 查詢方式

hibernate共有三種查詢方式 hql qbc和sql hql寫起來靈活直觀,而且與所熟悉的sql的語法類似。條件查詢 分頁查詢 連線查詢 巢狀查詢,包括一些查詢函式 count sum 等 查詢條件的設定等寫起來與sql語法一致,主要區別就是把表名換成了類或者物件。注意 在hql中關鍵字不區分...

Hibernate檢索方式

hibernate 的檢索方式有5種。customer c session.get customer.class,2 c.getorders size 可以根據已經載入的物件導航到其他物件,如一對多的查詢。session.get customer.class,3 session.load order...