SpringBoot整合Redis缓存主页信息
前因
温馨提醒:阅读本文需要6分钟
半藏商城之前的主页信息都是可以在后台管理系统中进行配置的,但是每次打开主页都会访问数据库进行读取,会造成不必要的资源浪费。所以就加入了redis缓存将首页信息放到服务器的redis中。接下来分享一下我的整个Redis缓存的代码实现流程。
安装Redis
首先在服务器上安装Redis(百度有很详细的步骤),要说明的是最好不好使用默认端口号6379,同时还要在redis.conf中设置密码,修改端口,开放端口访问(最好不要全部开放,可以只开放自己的ip,之前我的服务器因为没有设置redis的密码和限制端口被注入了挖矿病毒),最后一定不要忘记在阿里云的控制台增加redis配置的端口的安全组访问权限。
Maven引包
首先进行在pom.xml中进行引包,还在为引哪个版本的包而困扰的同学推荐这个Maven在线查找依赖的网站,想用什么输入搜索,复制过来就可以了。spring-boot-starter-data-redis:在 Spring Boot 2.x 以后底层不再使用 Jedis,而是换成了 Lettuce。commons-pool2用作 Redis 连接池,如不引入启动会报错。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <dependency> groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.67</version> </dependency>
配置Redis连接信息
#SpringBoot通过lettuce配置Redis spring.redis.host=你的服务器公网ip spring.redis.port=redis端口号 #密码 spring.redis.password=redis密码 # 连接池最大连接数(使用负值表示没有限制) 默认为8 spring.redis.lettuce.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认为-1 spring.redis.lettuce.pool.max-wait=-1ms # 连接池中的最大空闲连接 默认为8 spring.redis.lettuce.pool.max-idle=8 # 连接池中的最小空闲连接 默认为 0 spring.redis.lettuce.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.lettuce.shutdown-timeout=5000
配置RedisConfig信息
默认情况下的模板只能支持 RedisTemplate<String, String>,也就是只能存入字符串,所以自定义模板很有必要。在config包添加配置RedisConfig.java。
@EnableCaching @Configuration public class RedisConfig extends CachingConfigurerSupport { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisSerializer<Object> serializer = redisSerializer(); RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(serializer); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(serializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } @Bean public RedisSerializer<Object> redisSerializer() { //创建JSON序列化器 Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); serializer.setObjectMapper(objectMapper); return serializer; } @Bean public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); //设置Redis缓存有效期为1天 RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer())).entryTtl(Duration.ofDays(1)); return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration); } }
编写业务层和实现
/** * redis操作Service * Created on 2020/3/23 */ public interface RedisService { /** * 保存属性 */ void set(String key, Object value, long time); /** * 保存属性 */ void set(String key, Object value); /** * 获取属性 */ Object get(String key); /** * 删除属性 */ Boolean del(String key); /** * 批量删除属性 */ Long del(List<String> keys); /** * 设置过期时间 */ Boolean expire(String key, long time); /** * 获取过期时间 */ Long getExpire(String key); /** * 判断是否有该属性 */ Boolean hasKey(String key); /** * 按delta递增 */ Long incr(String key, long delta); /** * 按delta递减 */ Long decr(String key, long delta); /** * 获取Hash结构中的属性 */ Object hGet(String key, String hashKey); /** * 向Hash结构中放入一个属性 */ Boolean hSet(String key, String hashKey, Object value, long time); /** * 向Hash结构中放入一个属性 */ void hSet(String key, String hashKey, Object value); /** * 直接获取整个Hash结构 */ Map<Object, Object> hGetAll(String key); /** * 直接设置整个Hash结构 */ Boolean hSetAll(String key, Map<String, Object> map, long time); /** * 直接设置整个Hash结构 */ void hSetAll(String key, Map<String, Object> map); /** * 删除Hash结构中的属性 */ void hDel(String key, Object... hashKey); /** * 判断Hash结构中是否有该属性 */ Boolean hHasKey(String key, String hashKey); /** * Hash结构中属性递增 */ Long hIncr(String key, String hashKey, Long delta); /** * Hash结构中属性递减 */ Long hDecr(String key, String hashKey, Long delta); /** * 获取Set结构 */ Set<Object> sMembers(String key); /** * 向Set结构中添加属性 */ Long sAdd(String key, Object... values); /** * 向Set结构中添加属性 */ Long sAdd(String key, long time, Object... values); /** * 是否为Set中的属性 */ Boolean sIsMember(String key, Object value); /** * 获取Set结构的长度 */ Long sSize(String key); /** * 删除Set结构中的属性 */ Long sRemove(String key, Object... values); /** * 获取List结构中的属性 */ List<Object> lRange(String key, long start, long end); /** * 获取List结构的长度 */ Long lSize(String key); /** * 根据索引获取List中的属性 */ Object lIndex(String key, long index); /** * 向List结构中添加属性 */ Long lPush(String key, Object value); /** * 向List结构中添加属性 */ Long lPush(String key, Object value, long time); /** * 向List结构中批量添加属性 */ Long lPushAll(String key, Object... values); /** * 向List结构中批量添加属性 */ Long lPushAll(String key, Long time, Object... values); /** * 从List结构中移除属性 */ Long lRemove(String key, long count, Object value); }
/** * redis操作实现类 * Created n 2020/3/23 */ @Service public class RedisServiceImpl implements RedisService { @Resource private RedisTemplate<String, Object> redisTemplate; @Override public void set(String key, Object value, long time) { redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); } @Override public void set(String key, Object value) { redisTemplate.opsForValue().set(key, value); } @Override public Object get(String key) { return redisTemplate.opsForValue().get(key); } @Override public Boolean del(String key) { return redisTemplate.delete(key); } @Override public Long del(List<String> keys) { return redisTemplate.delete(keys); } @Override public Boolean expire(String key, long time) { return redisTemplate.expire(key, time, TimeUnit.SECONDS); } @Override public Long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } @Override public Boolean hasKey(String key) { return redisTemplate.hasKey(key); } @Override public Long incr(String key, long delta) { return redisTemplate.opsForValue().increment(key, delta); } @Override public Long decr(String key, long delta) { return redisTemplate.opsForValue().increment(key, -delta); } @Override public Object hGet(String key, String hashKey) { return redisTemplate.opsForHash().get(key, hashKey); } @Override public Boolean hSet(String key, String hashKey, Object value, long time) { redisTemplate.opsForHash().put(key, hashKey, value); return expire(key, time); } @Override public void hSet(String key, String hashKey, Object value) { redisTemplate.opsForHash().put(key, hashKey, value); } @Override public Map<Object, Object> hGetAll(String key) { return redisTemplate.opsForHash().entries(key); } @Override public Boolean hSetAll(String key, Map<String, Object> map, long time) { redisTemplate.opsForHash().putAll(key, map); return expire(key, time); } @Override public void hSetAll(String key, Map<String, Object> map) { redisTemplate.opsForHash().putAll(key, map); } @Override public void hDel(String key, Object... hashKey) { redisTemplate.opsForHash().delete(key, hashKey); } @Override public Boolean hHasKey(String key, String hashKey) { return redisTemplate.opsForHash().hasKey(key, hashKey); } @Override public Long hIncr(String key, String hashKey, Long delta) { return redisTemplate.opsForHash().increment(key, hashKey, delta); } @Override public Long hDecr(String key, String hashKey, Long delta) { return redisTemplate.opsForHash().increment(key, hashKey, -delta); } @Override public Set<Object> sMembers(String key) { return redisTemplate.opsForSet().members(key); } @Override public Long sAdd(String key, Object... values) { return redisTemplate.opsForSet().add(key, values); } @Override public Long sAdd(String key, long time, Object... values) { Long count = redisTemplate.opsForSet().add(key, values); expire(key, time); return count; } @Override public Boolean sIsMember(String key, Object value) { return redisTemplate.opsForSet().isMember(key, value); } @Override public Long sSize(String key) { return redisTemplate.opsForSet().size(key); } @Override public Long sRemove(String key, Object... values) { return redisTemplate.opsForSet().remove(key, values); } @Override public List<Object> lRange(String key, long start, long end) { return redisTemplate.opsForList().range(key, start, end); } @Override public Long lSize(String key) { return redisTemplate.opsForList().size(key); } @Override public Object lIndex(String key, long index) { return redisTemplate.opsForList().index(key, index); } @Override public Long lPush(String key, Object value) { return redisTemplate.opsForList().rightPush(key, value); } @Override public Long lPush(String key, Object value, long time) { Long index = redisTemplate.opsForList().rightPush(key, value); expire(key, time); return index; } @Override public Long lPushAll(String key, Object... values) { return redisTemplate.opsForList().rightPushAll(key, values); } @Override public Long lPushAll(String key, Long time, Object... values) { Long count = redisTemplate.opsForList().rightPushAll(key, values); expire(key, time); return count; } @Override public Long lRemove(String key, long count, Object value) { return redisTemplate.opsForList().remove(key, count, value); } }
存储Redis缓存信息
接下来就需要开始调用redis来进行存储和读取信息。我在商城的首页的轮播图和分类,新品等页面都进行了redis处理,接下来只贴出轮播图的代码实现情况。在将实体信息存储到redis中的时候,我是采用alibaba的fastjson进行序列化处理。
@Override public List<HanZoMallIndexCarouselVO> getCarouselsForIndex(int number) { List<HanZoMallIndexCarouselVO> hanZoMallIndexCarouselVOS = new ArrayList<>(number); String key = "redis:list:indexCarousel"; boolean exists =redisService.hasKey(key); if (exists){ //redis中存在key 不需要从数据库中读取 log.debug("redis中存在key:"+key); String indexCarousel =redisService.get(key).toString(); List<HanZoMallIndexCarouselVO> carousels = new ArrayList<>(number); if(indexCarousel!=null){ log.debug("从redis中读取轮播图信息--"); carousels = JSON.parseArray(indexCarousel,HanZoMallIndexCarouselVO.class); } return carousels; } List<Carousel> carousels = carouselMapper.findCarouselsByNum(number); if (!CollectionUtils.isEmpty(carousels)) { hanZoMallIndexCarouselVOS = BeanUtil.copyList(carousels, HanZoMallIndexCarouselVO.class); } log.info("更新一遍redis缓存"); String indexCarousel = JSON.toJSONString(hanZoMallIndexCarouselVOS); redisService.set(key,indexCarousel); redisService.expire(key,86400); return hanZoMallIndexCarouselVOS; }
小结
到此为止,整个Redis缓存主页信息的流程就介绍完毕了,知识只有分享出来才有价值。如果有问题的话,可以在关于我的页面,通过我的邮箱联系我进行探讨。
- spring boot整合Mybatis如何查询某一时间段内的信息
- spring boot整合quartz 任务信息存放到SqlServer数据库
- SpringBoot+spring-date-jpa+Hibernate 整合mysql 与sqlserver 配置文件信息
- SpringBoot整合Redis缓存2(十二)
- Jasypt : 整合spring boot加密应用配置文件敏感信息
- springboot 整合redis ,在项目启动时加载redis缓存
- Springboot整合redis缓存
- SpringBoot 2.3 整合redis缓存自定义序列化
- springBoot整合jpa和redis缓存
- SpringBoot Security 整合thymeleaf模板自定义登录页面,按需提示错误信息
- SpringBoot+spring-date-jpa+Hibernate 整合mysql 与sqlserver 配置文件信息
- springboot整合redis缓存
- 【个人学习】使用idea搭建SpringBoot,整合Mybatis、Thymeleaf,连接数据库,实现具有前端界面项目:主要功能登录,注册,个人信息查看、更改,不定时更新中...
- Springboot整合Redis缓存
- 基于SpringBoot从零构建博客网站 - 开发设置主页标识和修改个人信息功能
- springboot整合redis缓存的小demo
- springboot整合mqtt客户端订阅信息
- springboot 整合websocket 站内消息 (支持广播式和只给一人发送)单独信息发送 信息群发 统计连接数
- springboot整合redis缓存
- Springboot整合mybatis并配置redis缓存