如何在Spring Data JPA CRUDRepository中添加缓存功能

vir*_*sir 14 spring caching hibernate jpa jdbc

我想在findOne方法中添加"Cacheable"注释,并在删除或发生方法时逐出缓存.

我怎样才能做到这一点 ?

sev*_*ven 13

virsir,如果您使用Spring Data JPA(仅使用接口),还有一种方法.这就是我所做的,类似结构化实体的genereic dao:

public interface CachingDao<T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {

@Cacheable(value = "myCache")
T findOne(ID id);

@Cacheable(value = "myCache")
List<T> findAll();

@Cacheable(value = "myCache")
Page<T> findAll(Pageable pageable);

....

@CacheEvict(value = "myCache", allEntries = true)
<S extends T> S save(S entity);

....

@CacheEvict(value = "myCache", allEntries = true)
void delete(ID id);
}
Run Code Online (Sandbox Code Playgroud)

  • Spring文档不建议在接口中使用缓存注释. (3认同)
  • 你能解释一下为什么你使用 `@CacheEvict` 作为方法 `save` 吗??为什么不使用`@CachePut`?不会保存它正确更新缓存,因此不需要`@Cacheable`甚至在保存后运行(假设缓存仍然存在) (2认同)
  • @seven好!请注意,可以使用`@CacheConfig`注释`Repo`,因此`cache`名称将在`CachingDao`之外. (2认同)

War*_*Zhu 7

我认为基本上@七的答案是正确的,但有两个缺点:

  1. 我们无法定义通用接口,我担心我们必须单独声明每个具体接口,因为注释不能被继承,我们需要为每个存储库提供不同的缓存名称.

  2. savedelete应该是CachePut,而且findAll既要CacheableCacheEvict

    public interface CacheRepository extends CrudRepository<T, String> {
    
        @Cacheable("cacheName")
        T findOne(String name);
    
        @Cacheable("cacheName")
        @CacheEvict(value = "cacheName", allEntries = true)
        Iterable<T> findAll();
    
        @Override
        @CachePut("cacheName")
        T save(T entity);
    
        @Override
        @CacheEvict("cacheName")
        void delete(String name);
    }
    
    Run Code Online (Sandbox Code Playgroud)

参考


小智 5

我以以下方式解决了这个问题并且工作正常


public interface BookRepositoryCustom {

    Book findOne(Long id);

}
Run Code Online (Sandbox Code Playgroud)
public class BookRepositoryImpl extends SimpleJpaRepository<Book,Long> implements BookRepositoryCustom {

    @Inject
    public BookRepositoryImpl(EntityManager entityManager) {
        super(Book.class, entityManager);
    }

    @Cacheable(value = "books", key = "#id")
    public Book findOne(Long id) {
        return super.findOne(id);
    }

}
Run Code Online (Sandbox Code Playgroud)
public interface BookRepository extends JpaRepository<Book,Long>, BookRepositoryCustom {

}
Run Code Online (Sandbox Code Playgroud)


Mak*_*das 2

尝试提供 MyCRUDRepository (一个接口和一个实现),如下所述:向所有存储库添加自定义行为。然后您可以覆盖这些方法并添加注释:

findOne(ID id)
delete(T entity)
delete(Iterable<? extends T> entities)
deleteAll() 
delete(ID id) 
Run Code Online (Sandbox Code Playgroud)