日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hibernate二级/查询缓存的陷阱

發布時間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hibernate二级/查询缓存的陷阱 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這篇文章將介紹如何設置Hibernate二級和查詢緩存,它們如何工作以及最常見的陷阱。

休眠二級緩存是用于存儲實體數據的應用程序級緩存。 查詢緩存是一個單獨的緩存,僅存儲查詢結果。

這兩個緩存實際上是并存的,因為在很多情況下,我們都希望在沒有其他緩存的情況下使用它們。 如果使用得當,這些緩存可以通過減少命中數據庫的SQL語句的數量,以透明的方式提高性能。

第二級緩存如何工作?

第二級緩存存儲實體數據,但存儲實體本身。 數據以“脫水”格式存儲,該格式看起來像哈希圖,其中鍵是實體ID,而值是原始值列表。

這是有關二級緩存內容的外觀的示例:

*-----------------------------------------* | Person Data Cache | |-----------------------------------------| | 1 -> [ "John" , "Q" , "Public" , null ] | | 2 -> [ "Joey" , "D" , "Public" , 1 ] | | 3 -> [ "Sara" , "N" , "Public" , 1 ] | *-----------------------------------------*

當通過Id從數據庫entityManager.find()例如,使用entityManager.find()從對象加載對象時,或者遍歷惰性初始化關系時,將填充第二級緩存。

查詢緩存如何工作?

查詢高速緩存在概念上看起來像一個哈希圖,其中鍵由查詢文本和參數值組成,并且值是與查詢匹配的實體ID的列表:

*----------------------------------------------------------* | Query Cache | |----------------------------------------------------------| | ["from Person where firstName=?", ["Joey"] ] -> [1, 2] ] | *----------------------------------------------------------*

有些查詢不返回實體,而是僅返回原始值。 在那些情況下,值本身將存儲在查詢緩存中。 執行可緩存的JPQL / HQL查詢時,將填充查詢緩存。

這兩個緩存之間有什么關系?

如果正在執行的查詢先前已緩存了結果,則不會有SQL語句發送到數據庫。 而是從查詢緩存中檢索查詢結果,然后使用緩存的實體標識符訪問第二級緩存。

如果第二級緩存包含給定ID的數據,它將重新水化實體并返回它。 如果第二級緩存不包含該特定ID的結果,則將發出SQL查詢以從數據庫中加載實體。

如何在應用程序中設置兩個緩存

第一步是在類路徑中包含hibernate-ehcache jar:

<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-ehcache</artifactId><version>SOME-HIBERNATE-VERSION</version> </dependency>

需要將以下參數添加到EntityManagerFactory或SessionFactory的配置中:

<prop key="hibernate.cache.use_second_level_cache">true</prop> <prop key="hibernate.cache.use_query_cache">true</prop> <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop> <prop key="net.sf.ehcache.configurationResourceName">/your-cache-config.xml</prop>

首選使用EhCacheRegionFactory而不是SingletonEhCacheRegionFactory 。 使用EhCacheRegionFactory意味著Hibernate將為Hibernate緩存創建單獨的緩存區域,而不是嘗試重用應用程序中其他位置定義的緩存區域。

下一步是在文件your-cache-config.xml配置緩存區域設置:

<?xml version="1.0" ?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"updateCheck="false"xsi:noNamespaceSchemaLocation="ehcache.xsd" name="yourCacheManager"><diskStore path="java.io.tmpdir"/><cache name="yourEntityCache"maxEntriesLocalHeap="10000"eternal="false"overflowToDisk="false"timeToLiveSeconds="86400" /><cache name="org.hibernate.cache.internal.StandardQueryCache"maxElementsInMemory="10000"eternal="falsetimeToLiveSeconds="86400"overflowToDisk="false"memoryStoreEvictionPolicy="LRU" /><defaultCachemaxElementsInMemory="10000"eternal="false"timeToLiveSeconds="86400"overflowToDisk="false"memoryStoreEvictionPolicy="LRU" /> </ehcache>

如果未指定緩存設置,則采用默認設置,但是最好避免這種情況。 通過在ehcache元素中填充name屬性,確保為緩存命名。

為緩存指定一個名稱可以防止它使用默認名稱,該名稱可能已經在應用程序的其他位置使用過。

使用二級緩存

現在可以使用二級緩存了。 為了緩存實體,請使用@org.hibernate.annotations.Cache注釋對它們進行注釋:

@Entity @Cache(usage=CacheConcurrencyStrategy.READ_ONLY, region="yourEntityCache") public class SomeEntity {... }

關聯也可以由二級緩存進行緩存,但是默認情況下不這樣做。 為了啟用關聯的緩存,我們需要將@Cache應用于關聯本身:

@Entity public class SomeEntity {@OneToMany@Cache(usage=CacheConcurrencyStrategy.READ_ONLY,region="yourCollectionRegion")private Set<OtherEntity> other; }

使用查詢緩存

配置查詢緩存后,默認情況下尚未緩存任何查詢。 需要將查詢明確標記為已緩存,例如,這是如何將命名查詢標記為已緩存:

@NamedQuery(name="account.queryName",query="select acct from Account ...",hints={@QueryHint(name="org.hibernate.cacheable",value="true")} })

這是將條件查詢標記為已緩存的方法:

List cats = session.createCriteria(Cat.class).setCacheable(true).list();

下一節將介紹一些在嘗試設置這兩個緩存時可能遇到的陷阱。 這些行為按設計工作,但仍然令人驚訝。

陷阱1 –查詢緩存會降低性能,導致大量查詢

如果將緩存的查詢結果配置為比查詢返回的緩存的實體更頻繁地過期,則會發生兩個緩存的工作方式的有害副作用。

如果查詢已緩存結果,它將返回實體ID的列表,然后針對第二級緩存進行解析。 如果具有這些ID的實體未配置為可緩存或它們已過期,則每個實體ID的選擇將命中數據庫。

例如,如果一個緩存的查詢返回了1000個實體ID,而第二級緩存中沒有這些實體,則將對數據庫發出1000個ID選擇。

該問題的解決方案是將查詢結果到期配置為與查詢返回的實體的到期保持一致。

陷阱2 –與

當前無法為同一父實體的不同子類指定不同的緩存策略。

例如,這將不起作用:

@Entity @Inheritance @Cache(CacheConcurrencyStrategy.READ_ONLY) public class BaseEntity {... }@Entity @Cache(CacheConcurrencyStrategy.READ_WRITE) public class SomeReadWriteEntity extends BaseEntity {... }@Entity @Cache(CacheConcurrencyStrategy.TRANSACTIONAL) public class SomeTransactionalEntity extends BaseEntity {... }

在這種情況下,僅考慮父類的@Cache注釋,并且所有具體實體都具有READ_ONLY并發策略。

陷阱3 –使用基于單例的緩存時,緩存設置將被忽略

建議將緩存區域工廠配置為EhCacheRegionFactory ,并通過net.sf.ehcache.configurationResourceName指定ehcache配置。

此區域工廠的替代方法是SingletonEhCacheRegionFactory 。 對于該區域工廠,使用緩存名稱作為查找鍵將緩存區域存儲為單例。

單例區域工廠的問題在于,如果應用程序的另一部分已經在單例中注冊了具有默認名稱的緩存,則這將導致忽略通過net.sf.ehcache.configurationResourceName傳遞的ehcache配置文件。

結論

如果設置正確,則二級緩存和查詢緩存非常有用,但是要記住一些陷阱,以免發生意外行為。 總而言之,這是一個透明工作的功能,如果使用得當,可以顯著提高應用程序的性能。

翻譯自: https://www.javacodegeeks.com/2014/06/pitfalls-of-the-hibernate-second-level-query-caches.html

總結

以上是生活随笔為你收集整理的Hibernate二级/查询缓存的陷阱的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。