用户第一次请求,缓存中没有对应的数据,所以需要到数据库查询,查询的结果保存在缓存中,用户以后请求,直接从缓存中获取。用户获取的数据是经过service业务层处理的,而不是直接从数据库中获取到的数据,缓存的实现也需要在业务层进行。
1.手动实现
这里只给出最主要的地方代码。
配置文件
service业务层
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserMapper userMapper;
@Autowired
RedisTemplate<String, User> redisTemplate;
@Override
public User selectOneUser(Integer id) {
// 在redis数据库(缓存)中查找(以id作为key)
BoundValueOperations<String, User> ops = redisTemplate.boundValueOps(String.valueOf(id));
User user1 = ops.get();
// 如果查到,表示缓存中存有数据,直接返回
if (user1 != null) {
return user1;
}
System.out.println("====进入数据库====");
// 进入数据库,表明没有查到,需要到数据库查找
User user2 = userMapper.selectOneUser(id);
// 查到数据后,需要将数据放入缓存Cache中
ops.set(user2);
return user2;
}
@Override
public void deleteOneUser(Integer id) {
// 数据库删除数据,缓存需要同步删除(不需要bound绑定)
redisTemplate.delete(String.valueOf(id));
userMapper.deleteOneUser(id);
}
@Override
public void updateOneUser(User user) {
// 数据库更新,缓存中也需要更新,set直接覆盖旧数据
redisTemplate.boundValueOps(String.valueOf(user.getId())).set(user);
userMapper.updateOneUser(user);
}
}
2.注解实现
配置文件
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserMapper userMapper;
/**
* @Cacheable,缓存 方法的返回值,在第一次查询的时候进入
* cacheNames:缓存的名字
* key:redis数据库的键
* key是String,id是Integer,所以利用 +'' 转型成String
*/
@Cacheable(cacheNames= {"user_cache"},key="#id+''")
@Override
public User selectOneUser(Integer id) {
System.out.println("====进入数据库====");
User user2 = userMapper.selectOneUser(id);
return user2;
}
@CacheEvict(cacheNames= {"user_cache"},key="#id+''")
@Override
public void deleteOneUser(Integer id) {
userMapper.deleteOneUser(id);
}
/**
* 返回方法的返回值
* 每次都会进入方法
* key:如果是对象--->对象.属性名
*/
@CachePut(cacheNames= {"user_cache"},key="#user.id+''")
@Override
public User updateOneUser(User user) {
userMapper.updateOneUser(user);
return user;
}
}