spring boot整合reids 然后实现缓存分页(方法之一) 以及RedisTemplate存到reids 里面get 就消失的坑

时间:2024-05-18 23:36:26

业务需求 首页 实现缓存分页

spring boot 整合redis   (我的是2.0.3版本的)

在pom 文件写上依赖包即可

<dependency><!--依赖包-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency> <dependency><!--设置reids配置需要的依赖包-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

在application.yml里面配置 相关的信息  如下图

spring boot整合reids 然后实现缓存分页(方法之一) 以及RedisTemplate存到reids 里面get 就消失的坑

我是安装在本地windows上    host 127.0.0.1  安装在linux上需写上其IP地址

这个时候 就可以使用redis 进行相关操作

redis相关操作(我这里懒得写) 请参考https://blog.****.net/xiaochunping9987/article/details/37900361 这篇博客

但是使用 RedisTemplate 存List到redis 里面 get 一次就会消失     最后发现原因是没有对reids 进行相关设置 导致 redis的事务不一致 导致key 取一次就消失

所以强烈建议 先进行redis 配置 在去使用redis 存数据

配置类如下


package com.wechat.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer; /**
* @Auther: wxf
* @Date: 2018/7/10 15:20
*/
@Configuration
@EnableCaching//开启注解
public class RedisConfig {
//缓存管理器 spring boot 2.0后 配置缓存管理器 和2.0以前 不一样 根据自己的版本 配置
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisTemplate) {
return RedisCacheManager.create(redisTemplate);
}
// 以下两种redisTemplate*根据场景选择
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory); //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper); template.setValueSerializer(serializer);
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
     //这里设置redis事务一致
template.setEnableTransactionSupport(true);
return template;
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(factory);
stringRedisTemplate.setEnableTransactionSupport(true);
return stringRedisTemplate;
}
}

配置完后 就可以进行 reids 相关操作

现在进行 redis的 list分页的相关操作  最后两个方法 是比较重要的


package com.wechat.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @Auther: wxf
* @Date: 2018/7/4 16:43
*/
@Service
public class RedisService {
@Autowired
StringRedisTemplate stringRedisTemplate;
@Resource(name="stringRedisTemplate")
ValueOperations<String, String> valOpsStr; @Autowired
RedisTemplate<Object, Object> redisTemplate;
@Resource(name = "redisTemplate")
ValueOperations<Object, Object> valOpsObj; /**
* 根据指定key获取String
* @param key
* @return
*/
public String getStr(String key){
String s = valOpsStr.get(key); if(s==null){
return "暂无对应的值";
}else{
return s;
}
}
/**
* 设置Str缓存
* @param key
* @param val
*/
public void setStr(String key, String val){
valOpsStr.set(key,val); }
/**
* 删除指定key
* @param key
*/ public void del(String key){
stringRedisTemplate.delete(key);
}
/**
* 根据指定o获取Object
* @param o
* @return
*/
public Object getObj(Object o) {
Object o1 = valOpsObj.get(o);
if(o1==null){
return o1;
}else{
return o1;
}
} /**
* 设置obj缓存
* @param key
* @param value
*/
public void setObj(Object key, Object value){ valOpsObj.set(key, value);
} /**
* 删除Obj缓存
* @param o
*/
public void delObj(Object o){
redisTemplate.delete(o);
} /** 添加对象到redis 里面的list中
* redis中的 list 是双向的 所以添加的时候需要注意
* rightPush 先进先出 leftPush 先进后出 这里 需要注意
* @param key list 对应的key
* @param obj 需要存的对象
*/
public void addList(String key,Object obj){
redisTemplate.opsForList().rightPush(key,obj);
} /**
* opsForList().range(key, start, end); 取范围值 redis里面的list下标从0开始
* 流程 拿到key 对应的list 取 0 到 5 和 mysql的limt 类似 注意下标即可
* 从redis list 里面的获取数据分页
* @param key redis list 对应的key
* @param start 开始下标
* @param end 介绍下标
* @return 返回list给前端
*/
public List getListPage(String key, int start, int end){
return (List)redisTemplate.opsForList().range(key, start, end);
}
}
 

现在开始测试

package com.wechat.controller;
import com.wechat.dao.UserMapper;
import com.wechat.pojo.User;
import com.wechat.service.RedisService;
import com.wechat.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List; /**
* @Auther: wxf
* @Date: 2018/6/28 10:21
*/
@RestController
@Slf4j
public class TestContorller {
@Autowired
UserMapper userMapper;
@Autowired
UserService userService;
@Autowired
RedisService redisService; /**
* 查询所有用户到redis中
* @return
*/
@RequestMapping("/test")
public List<User> selectAll(){
Object user1 = redisService.getObj("user");
if(user1==null){
List<User> users = userMapper.selectAll();
redisService.setObj("user",users);
log.info("没有缓存走数据库");
return users;
}else{
List<User> listUser=(List)user1;
log.info("有缓存");
return listUser;
}
} /**
* 我这里是把 user 信息存到object 中的 所有我要取出来用RedisTemplate 进行对 list的操作
*
*/
@RequestMapping("/add")
public void addTest(){
List<User> user = (List)redisService.getObj("user");
for (User u: user) {
//这里循环user 把每个对象存到 redis中list中
redisService.addList("list",u);
} } /**
* 这里取key 对应的list 那0 到 1 下标的 对象 也就是2个对象
* @return
*/
@RequestMapping("/aaa")
public List aaa(){
return redisService.getListPage("list",0,1);
} }

第一次 进test请求 前端截图如下

spring boot整合reids 然后实现缓存分页(方法之一) 以及RedisTemplate存到reids 里面get 就消失的坑

后台 截图

spring boot整合reids 然后实现缓存分页(方法之一) 以及RedisTemplate存到reids 里面get 就消失的坑

没有缓存  直接走的数据库读数据

第二次请求 test

spring boot整合reids 然后实现缓存分页(方法之一) 以及RedisTemplate存到reids 里面get 就消失的坑

数据一样的

后台 不一样

spring boot整合reids 然后实现缓存分页(方法之一) 以及RedisTemplate存到reids 里面get 就消失的坑

有缓存 现在 只想 add请求

add没有返回值 所以 我们直接进redis 看

spring boot整合reids 然后实现缓存分页(方法之一) 以及RedisTemplate存到reids 里面get 就消失的坑

redis 里面已经多了 key 为list 的list集合数据的数据spring boot整合reids 然后实现缓存分页(方法之一) 以及RedisTemplate存到reids 里面get 就消失的坑

可以看到 只有两条数据了

实现 动态的分页   第一次返回给前端总条数  让前端把或者后端把页码分出来 然后根据前端传过来的页码和一页几条 来动态取list的区间值 实现redis 分页

总结 : spring boot 使用redis 很简单  但是 需要进行redis的相关配置和设置 不然就会出现 存一次 取一次 redis中的key 消失问题

   redis 没有直接分页的方法 现在根据区间值来分页  或许还有更好的方法  知道的大佬 希望在下面留言 谢谢!!!!