写点什么

SpringBoot 系列:Spring Boot 集成 redis,mongodb 原理书籍推荐

作者:Java高工P7
  • 2021 年 11 月 10 日
  • 本文字数:2091 字

    阅读完需:约 7 分钟

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


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


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);


}


/**


  • 获取用户信息,注解缓存

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
SpringBoot系列:Spring Boot集成redis,mongodb原理书籍推荐