通过redis进行缓存分页,通过SCAN扫描进行缓存更新

问题:当我们要添加缓存时,如果我们用了PageHelper时,PageHelper只会对查询语句有效(使用到sql的查询),那么如果我们把查询到的数据都添加到缓存时,就会无法进行分页;

此时我们选择将分页后的数据加入缓存,前端传入page和count表示查询页数和个数,我们将其拼接到查询物品key作为唯一key添加进入redis中,每次查询不同页数都会添加缓存,

但是,当我们数据进行更新时可能会导致所有添加的缓存都会与数据库不符合,所以每次更新我们都要将缓存进行删除操作,下次查询再次进行缓存~

下面我们使用PageHelper和redis做缓存分页

每次查询页码数和每页数量和对应的key拼接起来存入redis中、

下面我们使用redisClient存入redis,通过redisTemplate进行模糊扫描扫描对于key下各个页码的缓存,当内容进行更新时删除掉之前的缓存,当我们再次请求时才会去加缓存

直接看代码

👇

@Service

public class AAAAServiceImpl implements aaaaService {

@Autowired

private TIntegralPrizesMapper integralPrizesMapper;

@Resource

private RedisTemplate<String,String> redisTemplate;

@Autowired

private IRedisClient redisClient;

@Autowired

private AAAAOrderMapper aaaaMapper;

@Autowired

private AAAAServiceImpl aaaaService;

public static final String XXX_KEY="XXX_AS_";

@Override

public void addPrizes(AAAA aaaa) {

aaaa.setId(UUID.randomUUID().toString().replace("-",""));

aaaa.setCreateTime(new Date());

aaaa.setUpdateTime(new Date());

// 处理传入数据

aaaaMapper.addPrizes(aaaa);

//查询以XXX_KEY+aaaa.getxx()开头的所有缓存(count表示要查询的数量,我们可以大概设置一个最大值(不要太大,不然影响性能))

ScanOptions options=ScanOptions.scanOptions().match(XXX_KEY+aaaa.getxx()+"*").count(100).build();

Cursor<byte[]> cursor=redisTemplate.getConnectionFactory().getConnection().scan(options);

//循环查询数据

while (cursor.hasNext()){

//将得到的字符组转换为String

String key=new String(cursor.next());

//删除缓存

redisClient.delete(key);

}

try {

//关闭游标

cursor.close();

} catch (IOException e) {

e.printStackTrace();

}

}

@Override

public String deleteXX(AAAADTO aaaaDTO) {

//更新时间

aaaaDTO.setUpdateTime(new java.util.Date());

aaaaMapper.deleteSXPrizes(aaaaDTO);

ScanOptions options=ScanOptions.scanOptions().match(XXX_KEY+aaaDTO.getxx()+"*").count(100).build();

Cursor<byte[]> cursor=redisTemplate.getConnectionFactory().getConnection().scan(options);

while (cursor.hasNext()){

String key=new String(cursor.next());

redisClient.delete(key);

}

try {

cursor.close();

} catch (IOException e) {

e.printStackTrace();

}

return msg;

}

@Override

public PageInfo<XXXPrizes> selectXXX(AAADTO aaaDTO) {

//对于每一页设置唯一的key存入redis

String key = XXX_KEY+aaaDTO.getxx()

+"page="+aaaDTO.getPage()

+"count="+aaaDTO.getCount();

//查询缓存

String tagsStr = redisClient.get(key);

if (StrUtil.isNotBlank(tagsStr)) {

//将String解析

return JSON.parseObject(tagsStr, new TypeReference<PageInfo<XXXPrizes>>() {});

}

//pc进行分页

PageHelper.startPage(aaaDTO.getPage(),aaaDTO.getCount());

List<TIntegralPrizes> tX = aaaMapper.selectxxx(aaaDTO);

PageInfo<XXXPrizes> pageInfo=new PageInfo<>(tX);

//解决缓存穿透问题()当数据库为空时,给缓存一个值,使其不会一直访问数据库

//因为这里我们set的值为pageInfo所以不用关心这个问题

//转换为json字符串

//存入缓存

String strList = JSON.toJSONString(pageInfo);

redisClient.set(key, strList, 5 * ((int) (Math.random() * 4) + 1), TimeUnit.MINUTES);

return pageInfo;

}

}

以上就是一个缓存分页的例子,当然做缓存分页方法有很多,此方法仅供参考

相关推荐
摇滚侠3 分钟前
Spring Boot 3零基础教程,WEB 开发 自定义静态资源目录 笔记31
spring boot·笔记·后端·spring
摇滚侠5 分钟前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 遍历 笔记40
spring boot·笔记·thymeleaf
左灯右行的爱情14 分钟前
4-Spring SPI机制解读
java·后端·spring
橘子海全栈攻城狮1 小时前
【源码+文档+调试讲解】基于SpringBoot + Vue的知识产权管理系统 041
java·vue.js·人工智能·spring boot·后端·安全·spring
Json_2 小时前
学习springBoot框架-开发一个酒店管理系统,熟悉springboot框架语法~
java·spring boot·后端
kkkkk0211062 小时前
微服务学习笔记(黑马商城)
java·spring boot·spring·spring cloud·sentinel·mybatis·java-rabbitmq
阿里云云原生2 小时前
零代码改造 + 全链路追踪!Spring AI 最新可观测性详细解读
spring·云原生
冲鸭ONE3 小时前
新手搭建Spring Boot项目
spring boot·后端·程序员
数智顾问3 小时前
Flink ProcessFunction 与低层级 Join 实战手册:多流广告计费精确去重
java·spring boot·spring
Java水解3 小时前
【Spring】Spring事务和事务传播机制
后端·spring