spring boot 2.0.1.RELEASE hibernate 缓存 ehcache 详解

启用hibernate 缓存application.yml配置:

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:

    ENABLE_SELECTIVE,默认值,除非被@Cacheable显式声明要缓存,否则默认不缓存

    DISABLE_SELECTIVE,除非被@Cacheable显式声明不缓存,否则默认缓存

    ALL,总是被缓存

    NONE,总是不缓存

 

hibernate实现中只有三种缓存类型: 

一级缓存:默认启用,无法关闭,session级别, 同一个session内部,一级缓存生效,同一个id的对象只有一个。不同session,一级缓存无效

二级缓存:  sessionFactory级别,使用方式有两种:第一种不使用hibernate的@cache标记,直接在实体上用@cacheable(javax.persistence.Cacheable)标记并且要配置缓存配置项: javax.persistence.sharedCache.mode:ENABLE_SELECTIVE, 第二种用hibernate的@cache标记使用,

1、二级缓存针对列表数据默认只缓存id,再通过id从数据库中查找

2、二级缓存缓存的仅仅是对象,如果查询出来的是对象的一些属性,则不会被加到缓存中去

3、 只有当 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>

 

转载于:https://my.oschina.net/u/1428688/blog/2962103

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值