springboot整合redis实现分页

springboot整合redis实现分页

最近写springboot项目时遇到一个问题,就是使用redis实现分页。
在网上差了很多,看到了一个使用ZSet实现的,但是最后也没看懂,最后想了下想还是用list+map实现。

就拿做的订单分页来说,源码奉上

 public Result queryAllOrderHave(Integer userId,Integer pageNo,Integer pageSize) {
 	//用来判断这个用户是否存在,不展示这个方法的源码了
        if(orderMapper.userExistOrNo(userId)<=0) {
            return Result.fail("错误:用户不存在");
        }
        //获取该用户已支付订单的总记录数
        int allCount = orderMapper.haveOrderCount(userId);
        //这是封装的一个分页的方法,源码在下面展示
        Integer[] pageAndPageSize = PageUtil.getPageAndPageSize(allCount, pageNo, pageSize);
        if(pageAndPageSize==null){
            return Result.fail("请检查pageNo和pageSize");
        }
        //根据分页 显示出分页查询时需要的数据  redis中list的range 如果结束的位置超过总数量,默认为最后一个
        //显示该用户所有未支付订单
        //关键就在于后面的pageAndPageSize[0]和记录数pageAndPageSize[0]+pageAndPageSize[1]-1
        List<Object> range1 = redisUtil.range(RedisNameUtil.setOrderHave(userId),pageAndPageSize[0], pageAndPageSize[0]+pageAndPageSize[1]-1);
	//如果该key已经存在,直接从redis数据库里取,不用再遍历一遍
        if(redisUtil.hasKey(RedisNameUtil.setOrderHave(userId))){
            return Result.success(range1,allCount);
        }else{
		//从数据库查出数据
            Map<Object, Object> stringObjectMap = orderMapper.queryAllOrderHaveByUserId(userId);
            for (Map.Entry<Object,Object> entry : stringObjectMap.entrySet()){
		//将从数据里查出来的数据装到redis中的list集合内
                redisUtil.rightPush(RedisNameUtil.setOrderHave(userId), entry.getValue());
            }
		//和上面的一样了
            List<Object> range = redisUtil.range(RedisNameUtil.setOrderHave(userId), pageAndPageSize[0], pageAndPageSize[0]+pageAndPageSize[1]-1);
            return Result.success(range,allCount);
        }
    }

对源码的解释:

 List<Object> range1 = redisUtil.range(RedisNameUtil.setOrderHave(userId),pageAndPageSize[0], pageAndPageSize[0]+pageAndPageSize[1]-1);

redisUtil.range为封装的一个工具,用来自定义遍历redis里list的集合指定下标的数据 范围:[start,end]

/**
     * 自定义遍历的序列
     * @param key key
     * @param start 开始下标 (第一个0)
     * @param end 结束下标 (最后一个-1)
     * @return list
     */
    public List<Object> range(String key,long start,long end){
        try {
            if(!redisTemplate.hasKey(key)){
                return null;
            }
            return redisTemplate.opsForList().range(key,start,end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

接着是封装的分页工具类

/**
 * @Create on 2021/12/3 16:51
 */
public class PageUtil {
    public static Integer[] getPageAndPageSize(Integer allCount,Integer pageNo,Integer pageSize) {
        if (pageNo >= 1 && pageSize >= 1) {
            //第pageNo页 从第(pageNo-1)*pageSize个下标开始往下数
            int maxPage = (allCount % pageSize )== 0 ? (allCount / pageSize) : (allCount / pageSize) + 1;
            if (pageNo >= maxPage) {
                pageNo = (maxPage - 1) * pageSize;
            } else {
                pageNo = (pageNo - 1) * pageSize;
            }
            return new Integer[]{pageNo,pageSize};
        }else{
            return null;
        }
    }
}

可以看到,如果有问题的话返回的是null,否则返回一个Integer类型的数组

然后这两行是获取传进来的pageNo和pageSize

Integer[] pageAndPageSize = PageUtil.getPageAndPageSize(allCount, pageNo, pageSize);
List<Object> range1 = redisUtil.range(RedisNameUtil.setOrderHave(userId),pageAndPageSize[0], pageAndPageSize[0]+pageAndPageSize[1]-1);

关键来了,为什么后面的redisUtil.range()的start=pageAndPageSize[0],这个start是经过处理过的pageNo,和普通的分页没什么好说的,因为mysql里的limit是从第几行开始多少条数据,但是redisTemplate.opsForList().range(key,start,end)里的start和end表示从第几个下标开始,显示到第几个下标的数据。

简单来说,对于mysql:

SELECT * FROM table LIMIT 5,10; //检索第6条到第15条数据 共十条

对于redis

redisTemplate.opsForList().range(key,5,10); //检索第6条到第11条数据 共6条

pageAndPageSize[0]表示处理过的页码数,不难看出,处理过的页码数加上页面总数-1就和上面的limit一样了

即 pageAndPageSize[0]+pageAndPageSize[1]-1

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringBoot中,可以使用Redis实现分片集群。分片集群是将数据分散存储在多个Redis节点上,以提高性能和可扩展性。 有两种常见的分片集群方式可以用于SpringBoot整合Redis实现分片集群。 第一种方式是使用Redis Sentinel哨兵集群。在SpringBoot的配置文件中,可以指定哨兵集群的IP地址和端口号。通过使用哨兵集群,可以实现Redis的高可用性和故障转移。 第二种方式是使用Redis Cluster集群。同样在配置文件中,可以指定Redis Cluster集群的IP地址和端口号。Redis Cluster使用一致性Hash分片算法来将数据分布在多个节点上,从而实现数据的分片存储。 通过以上两种方式的配置,SpringBoot可以实现Redis的分片集群,从而提高系统的性能和可靠性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [基于SpringBoot实现单点登录的两种方式](https://download.csdn.net/download/m0_37776094/10640593)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [springboot整合redis集群](https://blog.csdn.net/weixin_45390688/article/details/125467210)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值