如何使用Spring数据JPA启用基本缓存
我正在尝试使用Spring数据JPA启用基本缓存。但是我无法理解为什么DAO方法仍然在查询数据库而不是使用缓存 给定以下Spring Boot 1.5.1应用程序如何使用Spring数据JPA启用基本缓存,spring,caching,spring-boot,spring-data,spring-data-jpa,Spring,Caching,Spring Boot,Spring Data,Spring Data Jpa,我正在尝试使用Spring数据JPA启用基本缓存。但是我无法理解为什么DAO方法仍然在查询数据库而不是使用缓存 给定以下Spring Boot 1.5.1应用程序 import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.Enab
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class Server{
public static void main(String[] args) {
SpringApplication.run(Server.class, args);
}
}
控制器
@Controller
public class PasswordsController {
@Autowired
private PasswordService service;
@SuppressWarnings("unchecked")
@RequestMapping("/passwords.htm")
public void passwords(Map model,
HttpServletRequest request) {
model.put("passwords", service.getPasswords(request));
}
...
服务
@Service
@Transactional
public class PasswordService extends BaseService {
@Autowired
private PasswordJpaDao passwordDao;
public Collection<Password> getPasswords(HttpServletRequest request) {
Collection<Password> passwords = passwordDao.getPasswords(params);
return passwords;
}
...
@服务
@交易的
公共类PasswordService扩展了BaseService{
@自动连线
私人密码jpadao passwordDao;
公共集合getPasswords(HttpServletRequest请求){
集合密码=passwordDao.getPasswords(params);
返回密码;
}
...
接口
@Transactional
public interface PasswordJpaDaoCustom {
public Collection<Password> getPasswords(PasswordSearchParameters params);
}
@Transactional
公共接口密码JPADAOCUSTOM{
公共集合getPasswords(PasswordSearchParameters参数);
}
和实施
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;
import com.crm.entity.Password;
import com.crm.search.PasswordSearchParameters;
@Transactional
@Repository
public class PasswordJpaDaoImpl implements PasswordJpaDaoCustom {
@PersistenceContext
private EntityManager em;
@Override
@Cacheable("passwords")
public Collection<Password> getPasswords(PasswordSearchParameters params) {
System.err.println("got here");
return em.createQuery(hql, Password.class);
}
...
import javax.persistence.EntityManager;
导入javax.persistence.PersistenceContext;
导入javax.persistence.Query;
导入javax.transaction.Transactional;
导入org.springframework.cache.annotation.Cacheable;
导入org.springframework.stereotype.Repository;
导入com.crm.entity.Password;
导入com.crm.search.PasswordSearchParameters;
@交易的
@存储库
公共类PasswordJpaDaoImpl实现了PasswordJpaDaoCustom{
@持久上下文
私人实体管理者;
@凌驾
@可缓存(“密码”)
公共集合getPasswords(PasswordSearchParameters参数){
System.err.println(“到达这里”);
返回em.createQuery(hql,Password.class);
}
...
Maven依赖项
<!-- Spring Boot start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Spring Boot end -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
</dependency>
org.springframework.boot
弹簧启动机自由标记器
org.springframework.boot
SpringBootStarterWeb
org.springframework.boot
弹簧启动安全
org.springframework.boot
弹簧靴启动器jdbc
org.springframework.boot
spring引导启动器数据jpa
org.springframework.boot
springbootstarter缓存
mysql
mysql连接器java
org.javassist
javassist
我知道Spring Boot会隐式地使用ConcurrentHashMap
进行缓存,而不需要任何特定的配置
但是
getPasswords()
dao方法总是被调用,而不是使用缓存。这是为什么?是的,spring boot默认使用ConcurrentHashMap
进行缓存,而代码的问题是您没有为密码缓存设置任何键,因此它每次都调用数据库以获取da助教
因此,您需要使用params
对象变量输入键(任何唯一标识符),如下所示:
@Cacheable(value="passwords", key="#params.id")//any unique identifier
public Collection<Password> getPasswords(PasswordSearchParameters params) {
System.err.println("got here");
return em.createQuery(hql, Password.class);
}
@Cacheable(value=“passwords”,key=“#params.id”)//任何唯一标识符
公共集合getPasswords(PasswordSearchParameters参数){
System.err.println(“到达这里”);
返回em.createQuery(hql,Password.class);
}
我无法提供来自“params”、“params”的唯一密钥只是搜索表单输入字段的封装,所有字段都可以为null。如果所有字段都为null,则返回所有密码。我是否仍可以缓存方法调用?否,您将获得java.lang.IllegalArgumentException:null key returned for cache operation
您可以设置一些默认键,例如“-1”或其他(特定于应用程序)谢谢,我将Cacheable
注释移动到了服务层,并使用了会话id来代替@Cacheable(value=“passwords”,key=“#request.session.id”)
。如果它们以@RequestParam
的形式出现,您可以设置defaultValue
,您可以查看这里: