通过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;

}

}

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

相关推荐
caihuayuan41 小时前
鸿蒙AI开发:10-多模态大模型与原子化服务的集成
java·大数据·sql·spring·课程设计
lyrhhhhhhhh1 小时前
MyBatis 延迟加载与缓存
sql·缓存·mybatis
张哈大1 小时前
【 Redis | 实战篇 秒杀优化 】
java·数据库·redis·笔记·缓存
Hello World......3 小时前
Java求职面试揭秘:从Spring到微服务的技术挑战
大数据·hadoop·spring boot·微服务·spark·java面试·互联网大厂
Hello World......3 小时前
互联网大厂Java面试:从Spring到微服务的全面探讨
java·spring boot·spring cloud·微服务·面试·技术栈·互联网大厂
拾贰_C4 小时前
【SpringBoot】MyBatisPlus(MP | 分页查询操作
java·spring boot·后端·spring·maven·apache·intellij-idea
Uranus^7 小时前
深入解析Spring Boot与JUnit 5的集成测试实践
spring boot·单元测试·集成测试·junit 5·mockito
就叫飞六吧9 小时前
Spring Security 集成指南:避免 CORS 跨域问题
java·后端·spring
秋野酱12 小时前
Spring Boot 项目的计算机专业论文参考文献
java·spring boot·后端
码视野12 小时前
基于Spring Boot和Vue的在线考试系统架构设计与实现(源码+论文+部署讲解等)
vue.js·spring boot·系统架构