很多时候系统的瓶颈都在一些比较复杂的IO操作,例如读取数据库,如果一些比较稳定的数据,一般的解决方案就是用缓存。spring boot提供了比较简单的缓存方案。只要使用 @EnableCaching即可完成简单的缓存功能。
缓存的实现有多种实现,ConcurentHashMapCache , GuavaCache, EnCacheCache等多种实现,spring boot 有默认的实现。本文不深入源码解读,首先用起来。
此处我们模拟要缓存的User
class User {
private Long id;
private String name;
// setter getter
}
然后我们业务对象:
import javax.annotation.PostConstruct;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.stereotype.Component;
/**
* @author micro
* @date 2017年8月2日
* @description :
*/
@Component
@EnableCaching
public class UserDao {
private Map<Long, User> userMap;
@PostConstruct
public void init() {
//模拟数据库
userMap = new HashMap<Long, User>();
userMap.put(1L, new User(1L,"micro1"));
userMap.put(2L, new User(2L, "micro2"));
}
@Cacheable("user") // 注解key属性可以执行缓存对象user(可以理解为一个map)的key
public User getUser(Long userId) {
System.out.println("查询数据库:userId ->" + userId);
return userMap.get(userId);
}
@Cacheable(value = "nameCache", key = "#name")
public User getUserByName(Long userId, String name) {
System.out.println("查询数据库:userId ->" + userId);
return userMap.get(userId);
}
@Cacheable("nameCache")
public User getUserByName(String name) {
System.out.println("查询数据库:userName : " + name);
for (Long k : userMap.keySet()) {
if (userMap.get(k).equals(name)) {
return userMap.get(k);
}
}
return null;
}
@CachePut("user") // 与Cacheable区别就是Cacheable先看缓存如果有,直接缓存换回,CachePut则是每次都会调用并且把返回值放到缓存
public User getUser2(Long userId) {
System.out.println("查询数据库:userId : " + userId);
return userMap.get(userId);
}
@CacheEvict("user")
public void removeFromCache(Long userId) {
return ;
}
}
然后我们编写启动类:
@SpringBootApplication
public class CacheTest implements CommandLineRunner {
@Autowired
private UserDao userDao;
public static void main(String[] args) {
new SpringApplication(CacheTest.class).run(args);
}
@Override
public void run(String... args) throws Exception {
System.out.println("第一次查询");
System.out.println(userDao.getUser(1L));
System.out.println("第二次查询");
System.out.println(userDao.getUser(1L));
userDao.removeFromCache(1L);// 移除缓存
System.out.println("第三次查询");
userDao.getUser(1L);// 没有缓存了
System.out.println("--------");
// 测试不同的key缓存
userDao.getUserByName("micro1");
userDao.getUserByName(1L, "micro1");// 指定了参数name 为key 此次读取缓存
}
}
打印结果:
第一次查询
查询数据库:userId ->1
User@65da01f4
第二次查询
User@65da01f4
第三次查询
查询数据库:userId ->1
--------
查询数据库:userName : micro1
发现能第二次查询拿了缓存,然后我们移除了,第三次又查数据库。然后我们还测试了指定不同参数为key的缓存。