工具: Spring-Boot:1.5.9.RELEASE Spring-Data-JPA:1.11.9.RELEASE
问题: 目前我有一个从JpaRepository扩展的存储库。为了避免频繁的DB访问,我想在JpaRepository中缓存一些CRUD方法。 我尝试了几种与Google先生无关的方法,但除了一个之外没有其他方法。
EDITED 1.此link中提到的解决方案是可行的。但是,这里有一个不好的做法(冗余给我)。想象一下,如果我有50个扩展JpaRepository的存储库,这意味着我必须覆盖50个存储库中的save方法。
public interface UserRepository extends CrudRepository<User, Long> {
@Override
@CacheEvict("user")
<S extends User> S save(S entity);
@Cacheable("user")
User findByUsername(String username);
}
EDITED 2.扩展JpaRepository接口。我看到了link2可能有用的东西。
在链接中,它提到了缓存JpaRepository方法的3种不同方法。第一种方法与我在#1中提到的相同。但是,我想要类似于第二/第三种方法的东西,以便我无需继续重复覆盖所有存储库中的CRUD方法。
以下是我编写的一些示例代码。
@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends
JpaRepository<T, ID> {
@CacheEvict
<S extends User> S save(S entity);
@Cacheble
T findOne(ID id);
}
@Repository
@CacheConfig("user")
public interface UserRepository extends BaseRepository<User, Integer> {
// when I calling findOne/save method from UserRepository, it should
// caching the methods based on the CacheConfig name defined in the
// child class.
}
然而,似乎代码(上面)不起作用,因为我得到了异常。我理解这个问题主要是因为没有为BaseRepository中的可缓存注释分配名称。但是我需要在从JpaRepository扩展的BaseRepository中缓存CRUD方法。
java.lang.IllegalStateException:无法解析'Builder [public abstract java.util.List com.sdsap.app.repository.BaseRepository.findAll()] caches = [] | key =''| keyGenerator =''| cacheManager =''| cacheResolver =''| condition =''|除非=''| sync ='false''使用解析器'org.springframework.cache.interceptor.SimpleCacheResolver@30a9fd0'。每个缓存操作应至少提供一个缓存。
我一直在问谷歌先生几天但却找不到合适的解决方案。我希望有人能在这里帮助我。对不起,如果我的问题不清楚或遗漏,因为这是我第一次在这里发帖。谢谢!
答案 0 :(得分:0)
对要缓存的方法使用@CachedResult
。
在您的主要课程中使用@EnableCaching
。
示例代码:
Main
类
@SpringBootApplication
@EnableCaching
@RestController
public class SpringBootCacheApplication {
@Autowired
SomeBean someBean;
@RequestMapping(value = "/cached/{key}")
public int getCachedMethod(@PathVariable("key") String key) {
System.out.println("Got key as " + key);
return someBean.someCachedResult(key);
}
public static void main(String[] args) {
SpringApplication.run(SpringBootCacheApplication.class, args);
}
}
我希望缓存的 SomeBean
类containsig方法
@Component
public class SomeBean {
@CacheResult
public int someCachedResult(String key) {
System.out.println("Generating random number");
int num = new Random().nextInt(200);
return num;
}
}
在someCachedResult
方法中,我总是返回一些随机值。自缓存以来,您只能在第一次获得随机值。
此处SomeBean
应与您的CachingUserRepository
类相对应。
答案 1 :(得分:0)
我假设您已经设置了所需的配置,并且您发布的堆栈跟踪是问题所在。所以让我们挖掘它。
我看到两个问题:
j ava.lang.IllegalStateException:无法解析缓存,每个缓存操作至少应提供一个缓存。
解决方案:每当您想要缓存数据或逐出数据时,必须提供缓存的名称,我在代码中没有看到。
应该定义@Cacheable's cacheNames or value以使缓存正常工作。
示例:@Cacheable(value = "usersCache")
正确的缓存密钥
由于缓存适用于key-value
对,因此您应该提供适当的缓存密钥。如果您没有提供缓存密钥,那么默认情况下,默认密钥生成策略会创建一个SimpleKey
,其中包含调用该方法的所有参数。
建议:您应手动提供缓存密钥。
示例:
@Cacheable(value = "usersCache", key = "#username")
User findByUsername(String username);
注意:请确保用户名是唯一的,因为缓存密钥必须是唯一的。