方法一:
实现分页查询可以在方法参数中增加两个参数:pageNum和pageSize。其中,pageNum表示要查询第几页,pageSize表示每页显示的数据条数。
private Set<String> getKeyDefineList0(String keyTemplate, int pageNum, int pageSize) {
// key 格式化
String key = StrUtil.replace(keyTemplate, "%[s|c|b|d|x|o|f|a|e|g]", parameter -> "*");
// 计算起始位置和结束位置
int startIndex = (pageNum - 1) * pageSize;
int endIndex = startIndex + pageSize - 1;
// scan 扫描 key
Set<String> keys = new LinkedHashSet<>();
stringRedisTemplate.execute((RedisCallback<Set<String>>) connection -> {
try (Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().match(key).count(100).build())) {
int index = 0;
while (cursor.hasNext()) {
byte[] value = cursor.next();
if (index >= startIndex && index <= endIndex) {
keys.add(StrUtil.utf8Str(value));
}
if (index > endIndex) {
break;
}
index++;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return keys;
});
return keys;
}
对代码得解析:
这是一个Java方法,其输入参数为keyTemplate、pageNum和pageSize,返回类型为Set<String>。
首先,该方法将keyTemplate中的占位符(%[s|c|b|d|x|o|f|a|e|g])替换为星号,得到格式化后的key。然后,根据传入的页码和页大小计算出查询的起始位置和结束位置。接着,通过Redis的SCAN命令扫描符合条件的key,并将结果存放在一个LinkedHashSet中。最后,返回该集合。
具体实现过程如下:
1、字符串keyTemplate中的占位符被星号替换,生成格式化后的key。
String key = StrUtil.replace(keyTemplate, "%[s|c|b|d|x|o|f|a|e|g]", parameter -> "*");
2、根据传入的pageNum和pageSize计算查询的起始位置和结束位置。
int startIndex = (pageNum - 1) * pageSize;
int endIndex = startIndex + pageSize - 1;
3、通过Redis的SCAN命令扫描符合条件的key,并将结果存放在一个LinkedHashSet中,只获取[startIndex, endIndex]范围内的key
Set<String> keys = new LinkedHashSet<>();
stringRedisTemplate.execute((RedisCallback<Set<String>>) connection -> {
try (Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().match(key).count(100).build())) {
int index = 0;
while (cursor.hasNext()) {
byte[] value = cursor.next();
if (index >= startIndex && index <= endIndex) {
keys.add(StrUtil.utf8Str(value));
}
if (index > endIndex) {
break;
}
index++;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return keys;
});
4、返回得到的key集合
return keys;
方法二:
用于检索与指定模式匹配的Redis键列表,并基于提供的pageNum和pageSize仅返回特定范围的键。
public List<String> findKeysForPage(String patternKey, int pageNum, int pageSize) {
ScanOptions options = ScanOptions.scanOptions().match(patternKey).build();
RedisConnectionFactory factory = stringRedisTemplate.getConnectionFactory();
RedisConnection rc = factory.getConnection();
Cursor<byte[]> cursor = rc.scan(options);
List<String> result = new ArrayList<String>(pageSize);
int tmpIndex = 0;
int startIndex = (pageNum - 1) * pageSize;
int end = pageNum * pageSize;
while (cursor.hasNext()) {
if (tmpIndex >= startIndex && tmpIndex < end) {
result.add(new String(cursor.next()));
tmpIndex++;
continue;
}
// 获取到满足条件的数据后,就可以退出了
if(tmpIndex >=end) {
break;
}
tmpIndex++;
cursor.next();
}
try {
// cursor.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
RedisConnectionUtils.releaseConnection(rc, factory);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
对代码得解析:
该方法接受三个参数:patternKey,即要匹配Redis键的模式,pageNum,请求的页码,以及pageSize,每页的项目数。
使用给定模式创建一个ScanOptions对象。
从StringRedisTemplate对象获取RedisConnectionFactory。
使用工厂打开Redis连接。
使用scan方法获取符合给定模式的所有键的游标。
初始化结果列表和一些索引变量。
循环遍历游标,直到没有更多项目或已达到所需页面大小为止。
如果当前项目满足分页条件,则将其添加到结果列表中。
如果向结果列表中添加了足够的项目,则退出循环。
关闭游标并释放Redis连接。
返回包含所选Redis键的结果列表。
请注意,出于安全考虑,代码被注释为关闭游标和释放Redis连接。