2017-04-01 62 views
2

我試圖啓用Spring Data JPA的基本緩存。但我不明白爲什麼DAO方法仍在查詢數據庫而不是使用緩存。如何使用Spring數據啓用基本緩存JPA

考慮下面的春季啓動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依賴

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

我明白,春天開機時會隱含使用ConcurrentHashMap緩存,而不需要任何特定的配置?

但是總是調用getPasswords() dao方法,而不是使用緩存。爲什麼是這樣?

回答

3

是,默認情況下彈簧Boot使用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); 
} 
+0

我無法從「PARAMS」提供了一個獨特的關鍵,「PARAMS」只是一個封裝搜索表單輸入字段,全部可以爲空。如果全部爲空,則返回所有密碼。我仍然可以緩存方法調用嗎? – crm

+0

不會,你會得到'java.lang.IllegalArgumentException:爲緩存操作返回空鍵' – developer

+0

你可以設置一些默認鍵,比如可以是「-1」或其他的東西(特定於應用程序) – developer

相關問題