启用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>