啓用hibernate 緩存application.yml配置:java
spring: jpa: properties: javax: persistence: sharedCache: mode: ENABLE_SELECTIVE hibernate: cache: use_query_cache: true use_second_level_cache: true region: factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
sharedCacheModel:git
ENABLE_SELECTIVE,默認值,除非被@Cacheable顯式聲明要緩存,不然默認不緩存github
DISABLE_SELECTIVE,除非被@Cacheable顯式聲明不緩存,不然默認緩存spring
ALL,老是被緩存sql
NONE,老是不緩存數據庫
hibernate實現中只有三種緩存類型: 緩存
一級緩存:默認啓用,沒法關閉,session級別, 同一個session內部,一級緩存生效,同一個id的對象只有一個。不一樣session,一級緩存無效session
二級緩存: sessionFactory級別,使用方式有兩種:第一種不使用hibernate的@cache標記,直接在實體上用@cacheable(javax.persistence.Cacheable)標記而且要配置緩存配置項: javax.persistence.sharedCache.mode:ENABLE_SELECTIVE, 第二種用hibernate的@cache標記使用,app
一、二級緩存針對列表數據默認只緩存id,再經過id從數據庫中查找less
二、二級緩存緩存的僅僅是對象,若是查詢出來的是對象的一些屬性,則不會被加到緩存中去
三、 只有當 HQL 查詢語句徹底相同時,連參數設置都要相同,此時查詢緩存纔有效
查詢緩存: 使用方式 queryImpl.setCacheable(true);必須設置纔會生效
查詢緩存緩存的也僅僅是對象的id,因此第一條 sql 也是將對象的id都查詢出來,可是當咱們後面若是要獲得每一個對象的信息的時候,此時又會發sql語句去查詢,因此,若是要使用查詢緩存,咱們必定也要開啓咱們的二級緩存,這樣就不會出現 N+1 問題了
private void setHibernateQuery(Query query) { if (query instanceof QueryImpl) { QueryImpl<?> queryImpl = (QueryImpl<?>) query; queryImpl.setCacheable(true); } }
ehcache.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?> <ehcache name="HIBERNATE_CACHE" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.ehcache.org/ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <!-- 指定二級緩存存放在磁盤上的位置,可使用磁盤目錄,也可使用Java System Property目錄,user.home是用戶目錄、user.dir是用戶當前工做目錄、java.io.tmpdir是默認臨時文件路徑 --> <diskStore path="target/cache/hibernate" /> <transactionManagerLookup class="net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup" properties="jndiName=java:/TransactionManager" propertySeparator=";" /> <defaultCache maxEntriesLocalHeap="0" eternal="false" diskPersistent="false" timeToIdleSeconds="3600" timeToLiveSeconds="0"> <!--<terracotta/> --> </defaultCache> <!--能夠給每一個實體類指定一個配置文件,經過name屬性指定,要使用類的全名 1. name:Cache的惟一標識。 2. maxElementsInMemory:內存中最大緩存對象數。 3. eternal:Element是否永久有效,一旦設置true,timeout將不起做用。 4. timeToIdleSeconds:設置Element在失效前的容許閒置時間。僅當element不是永久有效時使用,可選屬性,默認值是0,也就是可閒置時間無窮大。 5. timeToLiveSeconds:設置Element在失效前容許存活時間。最大時間介於建立時間和失效時間之間。僅當element不是永久有效時使用,默認是0.,也就是element存活時間無窮大。 6. overflowToDisk:配置此屬性,當內存中Element數量達到maxElementsInMemory時,Ehcache將會Element寫到磁盤中。 7. maxElementsOnDisk:磁盤中最大緩存對象數,如果0表示無窮大。 8. memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理緩存中的內容。默認策略是LRU(最近最少使用),你也能夠設置爲FIFO(先進先出)或是LFU(較少使用) 9. diskSpoolBufferSizeMB : 這個參數設置DiskStore(磁盤緩存)的緩存區大小。默認是30MB。每一個Cache都應該有本身的一個緩衝區 10. maxEntriesLocalHeap堆內存中最大緩存對象數,0沒有限制(必須設置) 11. maxEntriesLocalDisk硬盤最大緩存個數 --> <cache name="org.hibernate.cache.internal.StandardQueryCache" maxEntriesLocalHeap="0" eternal="false" timeToIdleSeconds="1200"> <persistence strategy="localTempSwap" /> </cache> <cache name="org.hibernate.cache.spi.UpdateTimestampsCache" maxEntriesLocalHeap="5000" eternal="true"> <persistence strategy="localTempSwap" /> </cache> </ehcache>
org.springframework.cache.annotation.Cacheable註解使用異常問題:
java.lang.IllegalArgumentException: Cannot find cache named '緩存名' for Builder[加了cacheable註解的方法名] caches=[緩存名] | key='#groupName' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'
@Cacheable(value = "findByGroup", key = "#groupName")
若是findByGroup未在ehcache.xml中配置,會出現沒法找到緩存名的異常,可使用CaffeineCacheManager或其餘的緩存組件做爲應用層緩存替換掉EhCacheCacheManager,就能夠不用配置緩存名了,數據庫緩存仍是使用的ehcache,不會產生影響
@EnableCaching @Configuration public class BcCacheManagerConfig { @Bean @ConditionalOnMissingBean(CacheManager.class) public CaffeineCacheManager caffeineCacheManager() { return new CaffeineCacheManager(); } }
相關包引入
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> ---------------------------------------------------------------------------- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.github.ben-manes.caffeine/caffeine --> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> </dependency> <!-- 集成ehcache須要的依賴 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-ehcache</artifactId> <exclusions> <exclusion> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> </exclusion> </exclusions> </dependency>