SpringBoot 系列:Spring Boot 集成 redis,mongodb 原理书籍推荐
redisTemplate.setValueSerializer(serializer);
// 使用 StringRedisSerializer 来序列化和反序列化 redis 的 key 值
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
@Configuration 表示这是一个配置类,@EnableCaching 用于开启缓存。当配置类 @Configuration 和 @EnableCaching 一起注解时,会触发一个 post processor,这会扫描每一个 spring bean,查看是否已经存在注解对应的缓存。如果找到了,就会自动创建一个代理拦截方法调用,使用缓存的 bean 执行处理。
@Bean 表示注入一个 Bean 对象,其中使用 Jackson2JsonRedisSerializer 来序列化和反序列化 Redis 的 value 值,StringRedisSerializer 来序列化和反序列化 redis 的 key 值。需要一提的事,当多个系统使用同一个(实际通常是同一个 Redis 集群)时,需要保证每个系统的序列化和反序列化方式一致。
接着我们创建一个 CacheDao,提供了 set 与 get 方法用于添加和获取缓存,缓存时间这里设置了一分钟。
@Repository
public class CacheDao {
@Resource
private RedisTemplate<String, Object> template;
public void set(String key, Object value){
System.out.println("添加缓存 key->" + key);
ValueOperations<String, Object> valueOperations = template.opsForValue();
// 1 分钟过期
valueOperations.set(key, value, 1, TimeUnit.MINUTES);
}
public Object get(String
key){
System.out.println("获取缓存 key->" + key);
ValueOperations<String, Object> valueOperations = template.opsForValue();
return valueOperations.get(key);
}
}
那么缓存是否起到了作用呢,我们添加测试类 UserApi,这是一个 Controller,提供添加用户和获取用户的方法。
@RestController
@RequestMapping("user")
public class UserApi {
@Autowired
private UserService userService;
/**
添加用户
@param user
*/
@PostMapping("addUser")
public String addUser(User user){
int id = userService.addUser(user);
return "添加用户成功,主键 id:" + id;
}
/**
获取用户信息
@param id
@return
*/
@GetMapping("getUser")
public User getUser(@RequestParam(value = "id") int id){
return userService.getUser(id);
}
}
接下来是 UserService,与之相对应的保存用户和获取用户的方法。IUserDao 使用了 mybatis,从数据库中获取,这里就不贴具体的代码了,而 CacheDao 则是上面展示过的,从缓存中读取。在添加用户的时候,我们将用户同时添加到缓存,或取用户的时候,我们将先从缓存中获取,如果缓存中不存在,则去数据库中查找,并同时进行缓存。
@Service
public class UserService {
@Autowired
private IUserDao userDao;
@Autowired
private CacheDao cacheDao;
/**
添加用户
@param user
*/
public int addUser(User user){
userDao.add(user);
// 添加缓存
cacheDao.set("user:id:" + user.getId(), user);
return user.getId();
}
/**
获取用户信息
@param id
@return
*/
public User getUser(int id){
// 从缓存中获取
User user = (User)cacheDao.get("user:id:" + id);
if(user == null){
user = userDao.find(id);
cacheDao.set("user:id:" + user.getId(), user);
}
return user;
}
}
启动项目,下面我们通过 swagger-ui 进行测试(本项目已经集成了 swagger2),我们添加张三、password 的数据。
调用结果显示成功,且 id 为 1。
然后我们去获取这条数据,使用/user/getUser 接口,可以成功获取。
然后我们查看后台打印的信息,先是调用了缓存,然后又进行了查询数据库,诶……这好像不对啊,我刚刚添加时不是进行缓存了吗,为什么没有生效?
这是因为我在获取的时候已经超过了缓存生效时间 1 分钟,这时再次查询,就不会去数据库中查询了。
三、注解方式使用 Redis
在 Spring Boot 项目中,注解满天飞,其实也可以使用注解形式进行缓存,该机制依赖于 Spring CaChe,但是这种方式一般较少,因为其缓存机制依赖方法的入参和返回结果,缺乏一定的灵活性。
缓存的注解主要有 @CachePut、@Cacheable、@CacheEvict,都作用于方法上。
@CachePut,添加缓存,key 可以从入参中获取,value 为方法返回值,注意并不是注解的 value 属性,value 属性是用于表示缓存的空间,例如 @CachePut(value=“user”, key="‘anno:user?’ + #user.id"),当然这必须要求方法有返回值,否则缓存的数据为空。
@Cacheable,既是获取,也是存储,存在缓存则从缓存中获取,不存在则进行缓存,缓存值为方法返回值
@CacheEvict 表示清除缓存。
在 UserService 中,我们新增 updateUser 更新用户,使用了 @CacheEvict 注解,getUserAnno 获取用户,使用了 @Cacheable。
/**
修改用户信息
@param user
*/
// @CachePut,每次都会进行缓存添加,缓存值为方法返回值,该方法无返回值无法使用
// @CachePut(value="user", key="'anno:user:id:' + #user.id")
// 直接删除缓存,下次获取重新查库
@CacheEvict(value="user", key="'anno:user:id:' + #user.id")
public void updateUser(User user){
userDao.update(user);
}
/**
获取用户信息,注解缓存
评论