查询redis 分页工具类
1.PageUtil
package com.demo.admin.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* @description: redis分页工具
* @author: fcy
* @time: 2022/2/14 13:37
*/
@Component
public class PageUtil {
@Resource
private RedisTemplate redisTemplate;
/**
* 存放单个hash缓存
*
* @param key 键
* @param hkey 键
* @param value 值
* @return
*/
public boolean hput(String key, String hkey, Object value) {
try {
redisTemplate.opsForHash().put(key, hkey, value);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 分页存取数据
*
* @param key hash存取的key
* @param hkey hash存取的hkey
* @param score 指定字段排序
* @param value
* @return
*/
public boolean setPage(String key, String hkey, double score, String value) {
boolean result = false;
try {
result = redisTemplate.opsForZSet().add(key + ":page", hkey, score);
//result = hput(key, hkey, value);
} catch (Exception e) {
e.printStackTrace();
}
//设置辅助分页的过期时间
redisTemplate.expire(key + ":page", 1800000, TimeUnit.MILLISECONDS);
//redisTemplate.expire(key,60000 , TimeUnit.MILLISECONDS);
return result;
}
/**
* 分页取出 hash中hkey值
*
* @param key
* @param offset
* @param count
* @return
*/
public Set<String> getPage(String key, int offset, int count) {
Set<String> result = null;
try {
result = redisTemplate.opsForZSet().rangeByScore(key + ":page", 1, 100000, (offset - 1) * count, count);//1 100000代表score的排序氛围值,即从1-100000的范围
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 计算key值对应的数量
*
* @param key
* @return
*/
public Integer getSize(String key) {
Integer num = 0;
try {
Long size = redisTemplate.opsForZSet().zCard(key + ":page");
return size.intValue();
} catch (Exception e) {
e.printStackTrace();
}
return num;
}
}
1.RedisFurryAndPageQueryUtil
package com.demo.admin.util;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.demo.admin.api.entity.otc.OtcAssetsInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
/**
* @description:
* @author: fcy
* @time: 2022/2/14 13:47
*/
@Component
public class RedisFurryAndPageQueryUtil<T> {
/**
* 插入辅助分页
*/
@Resource
private PageUtil pageUtil;
/**
* 注入redis模板工具
*/
@Resource
private RedisTemplate redisTemplate;
/**
* 根据条件进行模糊查询查询并返回分页结果
*
* @param name
* @param currentPage
* @param count
* @return
*/
public Page<T> find(String name, int currentPage, int count, String tableName, T t) {
//将传入的参数变为小写
name = StringUtils.lowerCase(name);
//map用来存储查询到的结果以及分页的总数据
// Map<String, Object> map = new HashMap<>();
Page<T> page = new Page<T>();
//用来存储查询到的ZhDicGoods
ArrayList<OtcAssetsInfo> result = new ArrayList<>();
//定义pageName用来查看redis中是否存在对应的辅助分页key-value
String pageName = tableName + name + ":page";
//是否存在对应的辅助分页辅助分页key-value
Boolean ifExist = redisTemplate.hasKey(pageName);
//如果不存在,生成辅助分页,同时查询
if (!ifExist) {
try {
Cursor<Map.Entry<String, String>> cursor = null;
//如果传入参数为空则查询所有
if (name == null || "".equals(name)) {
//模糊查询返回结果
//Cusor中存储的是查询key对应的Map
cursor = redisTemplate
.opsForHash()
//绑定模糊查询的hash的key
.scan(tableName, ScanOptions.scanOptions()
//模糊查询规则
.match("*")
.count(1000).build());
}else{
//模糊查询返回结果
//Cusor中存储的是查询key对应的Map
cursor = redisTemplate
.opsForHash()
//绑定模糊查询的hash的key
.scan(tableName, ScanOptions.scanOptions()
//模糊查询规则
.match("*"+name + "*")
.count(10000).build());
//生成分页key-value
setPage(cursor, name, tableName);
//生成查询结果并且放入map中
getPageResult(name, currentPage, count, page, result, tableName, t);
}
cursor.close();
} catch (Exception e) {
e.printStackTrace();
}
} else {
//有辅助分页key-value,直接查询结果放入map中
getPageResult(name, currentPage, count, page, result, tableName, t);
}
//返回result
return page;
}
/**
* 生成辅助分页
*
* @param cursor
* @param name:会在pageutil中自动加上:page
*/
private void setPage(Cursor<Map.Entry<String, String>> cursor, String name, String tableName) {
//setPage初始化值,zset的sort值
int i = 1;
//遍历模糊查询结果,将模糊查询的结果生成分页数据,用zset存储模糊查询的数据排序
//存储名称是查询name+:page,值是hash类型的key
while (cursor.hasNext()) {
Map.Entry<String, String> result = cursor.next();
//获取key
String key = result.getKey();
//存储对应的辅助分页数据
pageUtil.setPage(tableName + name, key, i, null);
i++;
}
}
/**
* 获取分页的总数据,并且加入到map中
*
* @param name
* @param currentPage
* @param count
* @param page
* @param result
*/
private void getPageResult(String name, int currentPage, int count, Page<T> page, ArrayList result, String tableName, T t) {
//得到分页数据总条数
Integer totalNumber = pageUtil.getSize(tableName + name);
//得到对应分页的key数组
Set<String> keyPages = pageUtil.getPage(tableName + name, currentPage, count);
//遍历循环查询对应cout对应的数据,同时转为对象输入到List
count = keyPages.size();
for (String keyPage : keyPages) {
//根据zset的key查询hash对应的数据
T Object = (T) redisTemplate.boundHashOps(tableName).get(keyPage);
result.add(Object);
}
//返回总页数
Integer pageCount = 0;
if (totalNumber % count == 0) {
pageCount = totalNumber / count;
} else {
pageCount = totalNumber / count + 1;
}
//加入返回实体类结果,总条数,起始页数,总条数
page.setCurrent(currentPage);
page.setSize(count);
page.setRecords(result);
page.setTotal(totalNumber);
page.setPages(pageCount);
}
}
junit 单元测试
package test;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.demo.admin.DemoApplication;
import com.demo.admin.api.entity.otc.OtcAssetsInfo;
import com.demo.admin.util.RedisFurryAndPageQueryUtil;
import com.demo.common.core.util.JsonMapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.util.Map;
/**
* @author :fcy
* @date :Created in 2022/2/15 17:04
* @description:
* @modified By:
*/
@Slf4j
@SpringBootTest(classes = DemoApplication.class)
// 让 JUnit 运行 Spring 的测试环境, 获得 Spring 环境的上下文的支持
@RunWith(SpringRunner.class)
public class MethodTestUtils {
@Resource
private RedisTemplate redisTemplate;
@Resource
private RedisFurryAndPageQueryUtil redisFurryAndPageQueryUtil;
@Test
public void testRedisPage(){
String tableName = "otcAssetsInfo";
// for (int i = 0; i < 25; i++) {
// OtcAssetsInfo otcAssetsInfo = new OtcAssetsInfo();
// otcAssetsInfo.setUnderlyingCode("123"+i);
// otcAssetsInfo.setUnderlyingName("测试资产1"+i);
// redisTemplate.opsForHash().put(tableName,otcAssetsInfo.getUnderlyingName(),otcAssetsInfo);
// }
Page<OtcAssetsInfo> page = redisFurryAndPageQueryUtil.find("", 1, 10, tableName, OtcAssetsInfo.class);
log.info(JsonMapper.INSTANCE.toJson(page));
log.info(JsonMapper.INSTANCE.toJson(page.getRecords()));
}
}
想学习,关注微信公众号 “Java追求”
版权声明:本文为qq_42274641原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。