Java 使用分页从redis缓存检索数据

Java 使用分页从redis缓存检索数据,java,caching,redis,spring-data-redis,Java,Caching,Redis,Spring Data Redis,我有如下结构的redis缓存 private HashOperations<String, Long, Object> hashOperations; //put data in cache hashOperations.put("Key", 1, SomeObject); 私有哈希操作; //将数据放入缓存 hashOperations.put(“Key”,1,SomeObject); 我需要通过分页从缓存中获取数据(第一页50个结果,第二页下一页50个结果,依此类推)。如何使

我有如下结构的redis缓存

private HashOperations<String, Long, Object> hashOperations;
//put data in cache
hashOperations.put("Key", 1, SomeObject);
私有哈希操作;
//将数据放入缓存
hashOperations.put(“Key”,1,SomeObject);

我需要通过分页从缓存中获取数据(第一页50个结果,第二页下一页50个结果,依此类推)。如何使用SpringDataRedis实现这一点。非常感谢您的帮助。

如果您需要保证元素的顺序,我认为您需要某种排序集(
HSCAN
是读取整个散列的好方法,但它不能保证返回内容的顺序,也不能保证返回内容中没有重复数据)。符合排序集描述的唯一Redis数据类型是:
ZSET
ZSET
s具有类似于
HASH
es的字段,但是在其字段中有一个
double
“score”,用于对字段进行排序,而不是字符串值

因此,要获得“hash paging”,您可以做的一件事是使用一个
ZSET
,其中的所有字段都与您的
hash
相同。
HASH
将包含字段中的数据,
ZSET
将跟踪它们的顺序

ZSET
s有一个名为
ZRANGE
()的方法,允许您从集合中获取特定数量的元素。对于50的“页面”大小,它将如下所示:

# this gets you the "page" with the first 50 elements
ZRANGE 0 50

# this gets you the "page" with the second 50 elements
ZRANGE 50 100

# etc.
因此,要向zset/hash添加一些数据,然后获得一个页面,您可以执行以下操作(伪代码-可能无法编译):

RedisTemplate-RedisTemplate;
字符串myKey=“exampleKey”;
//将一条记录添加到HASH+ZSET的示例
字符串myField=“field1”;
字符串myData=“123ABC”;
//在本例中,插入ZSET的数据是根据插入时间排序的。
//如果你想以不同的方式订购,你可以想出自己的计分方法
添加(myKey+“zset”,myField,System.getCurrentTimeMillis());
redisTemplate.opsForHash.put(mykey+“散列”、myField、myData);
//从散列中获取一页
设置first50hashFields=redisTemplate.opsForZSet().range(myKey+“zset”,0,50);
List firstPage=LinkedList();
for(字符串hashFieldKey:first50hashFields){
字符串hashFieldValue=redisTemplate.opsForHash().get(myKey+“hash”,hashFieldKey);
firstPage.add(hashFieldValue);
}

希望所有的字符串示例都足以说明如何做到这一点。

如果您需要保证元素的顺序,我认为您将需要某种排序集(
HSCAN
是读取整个散列的好方法,但它不能保证返回内容的顺序,也不能保证返回内容中没有重复数据)。符合已排序集描述的唯一Redis数据类型是:
ZSET
ZSET
s具有类似于
HASH
es的字段,但在其字段中有一个用于对字段进行排序的
double
“score”,而不是字符串值

因此,要获得“哈希分页”,您可以做的一件事是使用一个
ZSET
,其中包含与
hash
相同的字段。
hash
将包含字段中的数据,
ZSET
将跟踪它们的顺序

ZSET
s有一个名为
ZRANGE
()的方法,允许您从集合中获取特定数量的元素。对于50的“页面”大小,它如下所示:

# this gets you the "page" with the first 50 elements
ZRANGE 0 50

# this gets you the "page" with the second 50 elements
ZRANGE 50 100

# etc.
因此,要向zset/hash添加一些数据,然后获得一个页面,您可以执行以下操作(伪代码-可能无法编译):

RedisTemplate-RedisTemplate;
字符串myKey=“exampleKey”;
//将一条记录添加到HASH+ZSET的示例
字符串myField=“field1”;
字符串myData=“123ABC”;
//在本例中,插入ZSET的数据是根据插入时间排序的。
//如果你想以不同的方式订购,你可以想出自己的计分方法
添加(myKey+“zset”,myField,System.getCurrentTimeMillis());
redisTemplate.opsForHash.put(mykey+“散列”、myField、myData);
//从散列中获取一页
设置first50hashFields=redisTemplate.opsForZSet().range(myKey+“zset”,0,50);
List firstPage=LinkedList();
for(字符串hashFieldKey:first50hashFields){
字符串hashFieldValue=redisTemplate.opsForHash().get(myKey+“hash”,hashFieldKey);
firstPage.add(hashFieldValue);
}

希望所有的字符串示例都足以说明如何做到这一点。

我在网上找到了一些解决方法,并使用了相同的方法

@Override
    public List<Entity> findAll(final int pageNum, final int pageSize) {
        // Please validate the pageNum and pageSize in Controller that should be positive numbers
        int tmpIndex = 0;
        int tmpEndIndex = 0;
        final List<Entity> entities = new ArrayList<>();
        try (Cursor<Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(CACHE_KEY,
                ScanOptions.scanOptions().match("*").build())) {
            while (cursor.hasNext()) {
                if (tmpIndex >= pageNum && tmpEndIndex < pageSize) {
                    final Entry<Object, Object> entry = cursor.next();
                    final Entity entity = (Entity) entry.getValue();
                    entities.add(entity);
                    tmpIndex++;
                    tmpEndIndex++;
                    continue;
                }
                if (tmpEndIndex >= pageSize) {
                    break;
                }
                tmpIndex++;
                cursor.next();
            }
        } catch (Exception ex) {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("Exception while fetching data from redis cache : " + ex);
            }
        }
        return entities;
    }
@覆盖
公共列表findAll(final int pageNum,final int pageSize){
//请验证控制器中应为正数的pageNum和pageSize
int-tmpIndex=0;
int tmpEndIndex=0;
最终列表实体=新的ArrayList();
try(Cursor Cursor=redisTemplate.opsForHash().scan(CACHE_键,
ScanOptions.ScanOptions().match(“*”.build())){
while(cursor.hasNext()){
if(tmpIndex>=pageNum&&tmpendex=页面大小){
打破
}
tmpIndex++;
cursor.next();
}
}捕获(例外情况除外){
如果(LOGGER.IsInfo已启用()){
info(“从redis缓存获取数据时出现异常:”+ex);
}
}
返回实体;
}

我在网上找到了一些解决方法,并使用了相同的方法

@Override
    public List<Entity> findAll(final int pageNum, final int pageSize) {
        // Please validate the pageNum and pageSize in Controller that should be positive numbers
        int tmpIndex = 0;
        int tmpEndIndex = 0;
        final List<Entity> entities = new ArrayList<>();
        try (Cursor<Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(CACHE_KEY,
                ScanOptions.scanOptions().match("*").build())) {
            while (cursor.hasNext()) {
                if (tmpIndex >= pageNum && tmpEndIndex < pageSize) {
                    final Entry<Object, Object> entry = cursor.next();
                    final Entity entity = (Entity) entry.getValue();
                    entities.add(entity);
                    tmpIndex++;
                    tmpEndIndex++;
                    continue;
                }
                if (tmpEndIndex >= pageSize) {
                    break;
                }
                tmpIndex++;
                cursor.next();
            }
        } catch (Exception ex) {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("Exception while fetching data from redis cache : " + ex);
            }
        }
        return entities;
    }
@覆盖
公共列表findAll(final int pageNum,final int pageSize){
//请