我的springboot的缓存技术 博客写了 spring boot的缓存技术 主要用了 声明式缓存注解 。我写这篇博客是说一下不用注解方式使用 缓存的方法。
顺便说一下 GuavaCacheManager 的数据结构, GuavaCacheManager 类似是一种 Map<String,Map<Object,Object>>
的数据结构,GuavaCacheManager 里面有多个cache 每个cache 都有唯一的key
,每个cache是一个类似Map 的结构,有唯一的key 和value 。
本文案例,是项目启动时,将Person 表的数据都存在GuavaCacheManager 中,当查询数据时,从 GuavaCacheManager 中取,如果 GuavaCacheManager 中没有,则从数据库中取。
好了废话不多说,看主要的代码实现吧
1. 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!--缓存-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
2. 添加CacheConfig
新建 CacheConfig.java
服务启动后加载person 表中的数据到 GuavaCacheManager
package com.us.example.config;
import com.us.example.bean.Person;
import com.us.example.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.guava.GuavaCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* Created by yangyibo on 17/3/2.
*/
@Configuration
public class CacheConfig {
@Autowired
private DemoService demoService;
@Bean
public CacheManager getCacheManager() {
List<Person> personList = demoService.findAll();
//所有缓存的名字
List<String> cacheNames = new ArrayList();
GuavaCacheManager cacheManager = new GuavaCacheManager();
//最多缓存500 条,失效时间30分钟
cacheManager.setCacheSpecification("maximumSize=500,expireAfterWrite=30m");
//GuavaCacheManager 的数据结构类似 Map<String,Map<Object,Object>> map =new HashMap<>();
//将数据放入缓存
personList.stream().forEach(person -> {
//用person 的id cacheName
String cacheName=person.getId().toString();
if(cacheManager.getCache(cacheName)==null){
//为每一个person 如果不存在,创建一个新的缓存对象
cacheNames.add(cacheName);
cacheManager.setCacheNames(cacheNames);
}
Cache cache = cacheManager.getCache(cacheName);
//缓存对象用person的id当作缓存的key 用person 当作缓存的value
cache.put(person.getId(),person);
System.out.println("为 ID 为"+cacheName+ "的person 数据做了缓存");
});
return cacheManager;
}
}
3. service
然后在查询的时候,先去查询缓存,如果缓存没有则再去数据库查询
package com.us.example.service;
import com.us.example.bean.Person;
import com.us.example.dao.PersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
/**
* Created by yangyibo on 17/3/2.
*/
@Service
public class PersonService {
@Autowired
CacheManager cacheManager;
@Autowired
private PersonRepository personRepository;
public Person findOne(Long id) {
Person person = getCache(id, cacheManager);
if (person != null) {
System.out.println("从缓存中取出:" + person.toString());
} else {
person = personRepository.findOne(id);
System.out.println("从数据库中取出:" + person.toString());
}
return person;
}
public Person save(Person person) {
Person p = personRepository.save(person);
return p;
}
public Person getCache(Long id, CacheManager cacheManager) {
// Person person=(Person) cacheManager.getCache(id.toString()).get(id).get();
Cache cache = cacheManager.getCache(id.toString());
Cache.ValueWrapper valueWrapper = cache.get(id);
Person person = (Person) valueWrapper.get();
return person;
}
}
注意: 获取 Person 全部数据的 findAll() 方法 不要和使用缓存的 findOne 方法在同一个service 。
如果在同一个service 中则会在springboot 启动的时候报 bean 创建失败,依赖错误:
Injection of autowired dependencies failed