spring boot+spring data jpa +ehcache 缓存配置

pom.xml配置

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-ehcache</artifactId>
        </dependency>

boot启动文件

@EnableCaching//开启缓存
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
@SpringBootApplication
public class ShoppingApplication extends SpringBootServletInitializer {

实体类

@javax.persistence.Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE,region = BaseQueryService.CACHE)
public  class SystemRole extends BaseBean {

配置文件

spring.jpa.show-sql=true
spring.jpa.open-in-view=true
#统计
spring.jpa.properties.hibernate.generate_statistics=true
spring.jpa.properties.hibernate.javax.cache.missing_cache_strategy=create
spring.jpa.properties.hibernate.cache.format_sql=true
#开启查询缓存
spring.jpa.properties.hibernate.cache.use_query_cache=true
#缓存region 名称的前缀
spring.jpa.properties.hibernate.cache.region_prefix=lesson_cloud_
spring.jpa.properties.hibernate.cache.use_structured_entries=true
#要放在根目录下,不然就读取不到,这里指定的是@org.hibernate.annotations.Cache中的region 和setHint(QueryHints.HINT_CACHE_REGION, "")中的
spring.jpa.properties.hibernate.cache.provider_configuration_file_resource_path=ehcache.xml
#ENABLE_SELECTIVE除非明确标记为可缓存(使用@Cacheable注释),否则不会缓存实体。
spring.jpa.properties.javax.persistence.sharedCache.mode=ENABLE_SELECTIVE
#开启二级缓存
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
#指定缓存provider
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory


#这里指定的是使用org.springframework.cache.annotation等注解缓存配置
spring.cache.ehcache.config=classpath:config/ehcache.xml
spring.cache.type=ehcache

然后在是用的时候要注意

我使用的是Spring Data JPA中的JpaSpecificationExecutor进行构建查询

public interface BaseJpa<T, ID> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {
}

发现问题缓存无效

JpaSpecificationExecutor下的方法

 Optional<T> findOne(@Nullable Specification<T> spec);

List<T> findAll(@Nullable Specification<T> spec, Sort sort);
Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable);

 

这几个方法缓存都是无效的,但是其内部用@OneToOne等关联类的缓存是有效的

如findOne 查询到A,A中包含b

第一次进来,查询ab都被查,第二次,只查询了a,说明b缓存了。

而对于列表缓存,要通过@QueryHints去配置,太不智能了。

不知道有没有spring data jpa 通过代码设置缓存的

要使其查询条件和按照id查询能有效的进行缓存,我测试是通过entityManager才会生效

 List<SystemUser> list=  entityManager.createQuery("SELECT u "+
                "FROM\n" +
                " SystemUser u",SystemUser.class)
                .setHint(QueryHints.HINT_CACHE_REGION, "entityCache")
                .setHint(QueryHints.HINT_CACHEABLE, "true").getResultList();

参考资料

https://www.cnblogs.com/qianzf/p/7476847.html

http://www.spring4all.com/article/1443

http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#caching-config

https://juejin.im/post/5b2b5fc8f265da595d2ebf43

注解说明

org.springframework.cache.annotation.CacheEvict;
org.springframework.cache.annotation.Cacheable;
org.springframework.cache.annotation.Caching;

是针对spring.cache的缓存,内部也是可以指定ehcache的

而针对jpa,因为底层的实现是Hibernate,所以使用的是

javax.persistence.Cacheable
org.hibernate.annotations.Cache

然后再说说一级和二级

在spring data jpa中,同一个session是具有缓存的,如在一次请求流程中使用的都是同一个entityManager

而二级缓存是不同session中能共享缓存,这包含多次请求共享缓存

 

最主要的是天真的我认为直接使用

org.springframework.cache.annotation.CacheEvict;
org.springframework.cache.annotation.Cacheable;
org.springframework.cache.annotation.Caching;

这几个缓存可以缓存数据库查询结果,减少查询。然后发现在处理实体有OneToOne等关系的实体类的时候,增删改关联的实体类,缓存的没有办法去提示更新

想想解决方案是通过aop拦截,然后通过几个缓存存储记录好彼此关系,在修改的时候去更新。然而觉得代码量有点蛋碎,还是重复造轮子。

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值