如何使用Spring Data JPA启用基本缓存

时间:2017-04-01 08:54:12

标签: spring caching spring-boot spring-data spring-data-jpa

我正在尝试使用Spring Data JPA启用基本缓存。但我无法理解为什么DAO方法仍在查询数据库而不是使用缓存。

给出以下Spring Boot 1.5.1应用程序

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;
    }
...

接口

@Transactional
public interface PasswordJpaDaoCustom {

    public Collection<Password> getPasswords(PasswordSearchParameters params);
}

和实施

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);  
    }
...

Maven Dependencies

<!-- 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>

我知道Spring Boot会隐式使用ConcurrentHashMap进行缓存而无需任何特定配置吗?

但始终调用getPasswords() dao方法而不是使用缓存。这是为什么?

1 个答案:

答案 0 :(得分:3)

是的,默认情况下,春季启动会使用ConcurrentHashMap进行缓存,而代码的问题是您没有为key缓存设置任何passwords ,所以每次都要调用数据库来获取数据。

所以你需要使用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);  
}