下面列出了怎么用org.springframework.data.redis.core.Cursor的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* @Description: 从Redis获取博文点赞数
* @Param: []
* @return: java.util.List<com.zzx.model.pojo.Blog>
* @Author: Tyson
* @Date: 2020/5/30/0030 11:35
*/
public List<Blog> getBlogLikeCountFromRedis() {
List<Blog> blogList = new ArrayList<>();
try {
Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(RedisConfig.MAP_BLOG_LIKE_COUNT_KEY, ScanOptions.NONE);
while (cursor.hasNext()) {
Map.Entry<Object, Object> entry = cursor.next();
String key = (String)entry.getKey();
int blogId = Integer.parseInt(key);
int count = Integer.parseInt((String)entry.getValue());
Blog blog = new Blog(blogId, count);
blogList.add(blog);
//从redis删除key
redisTemplate.opsForHash().delete(RedisConfig.MAP_BLOG_LIKE_COUNT_KEY, key);
}
cursor.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return blogList;
}
/**
* 根据匹配删除redis key,如想删除 notify_ 开头的所有key match就为notify_*
*
* @author xuyisu
* @date 2018年7月18日
*
* @param match
*/
public void deleteByMatch(String match){
redisConnection = redisConnectionFactory.getConnection();
Cursor<byte[]> cursor = redisConnection.scan(new ScanOptions.ScanOptionsBuilder().match(match).build());
Set<String> set = new HashSet<String>();
while (cursor.hasNext()){
set.add((new String(cursor.next())));
if (set.size() >= 3000){
redisTemplate.delete(set);
set.clear();
}
}
if (set.size() > 0){
System.out.println(set.size());
redisTemplate.delete(set);
}
redisConnection.close();
}
/**
* 查找匹配key
* @param pattern key
* @return /
*/
public List<String> scan(String pattern) {
ScanOptions options = ScanOptions.scanOptions().match(pattern).build();
RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
RedisConnection rc = Objects.requireNonNull(factory).getConnection();
Cursor<byte[]> cursor = rc.scan(options);
List<String> result = new ArrayList<>();
while (cursor.hasNext()) {
result.add(new String(cursor.next()));
}
try {
RedisConnectionUtils.releaseConnection(rc, factory);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Scheduled(cron = "0 10 2 * * ?")
@Transactional(rollbackFor = Exception.class)
public void clear() {
System.out.println("开始清理收藏");
//获取keylist
final ScanOptions scanOptions = ScanOptions.scanOptions().match(RedisKeyConstant.ILLUST_BROWSING_HISTORY_REDIS_PRE + "*").build();
RedisConnection connection = stringRedisTemplate.getConnectionFactory().getConnection();
Cursor<byte[]> cursor = connection.scan(scanOptions);
int i = 0;
while (cursor.hasNext()) {
connection.zRemRangeByScore(cursor.next(), LocalDateTime.now().plusDays(-3).toEpochSecond(ZoneOffset.of("+8")), -Integer.MAX_VALUE);
i++;
}
illustHistoryMapper.deleteIllustHistory();
illustHistoryMapper.tempToIllustHistory();
illustHistoryMapper.truncateTemp();
}
@Override
public Cursor<V> scan(K key, final ScanOptions options) {
final byte[] rawKey = rawKey(key);
return execute(new RedisCallback<Cursor<V>>() {
@Override
public Cursor<V> doInRedis(RedisConnection connection) throws DataAccessException {
return new ConvertingCursor<byte[], V>(connection.sScan(rawKey, options), new Converter<byte[], V>() {
@Override
public V convert(byte[] source) {
return deserializeValue(source);
}
});
}
}, true);
}
@Override
public Cursor<TypedTuple<V>> scan(K key, final ScanOptions options) {
final byte[] rawKey = rawKey(key);
Cursor<Tuple> cursor = execute(new RedisCallback<Cursor<Tuple>>() {
@Override
public Cursor<Tuple> doInRedis(RedisConnection connection) throws DataAccessException {
connection.select(dbIndex);
return connection.zScan(rawKey, options);
}
}, true);
return new ConvertingCursor<Tuple, TypedTuple<V>>(cursor, new Converter<Tuple, TypedTuple<V>>() {
@Override
public TypedTuple<V> convert(Tuple source) {
return deserializeTuple(source);
}
});
}
@Override
public long removeByPattern(final String regex) throws IOException {
return withConnection(redisConnection -> {
long deletedCount = 0;
final List<byte[]> batchKeys = new ArrayList<>();
// delete keys in batches of 1000 using the cursor
final Cursor<byte[]> cursor = redisConnection.scan(ScanOptions.scanOptions().count(100).match(regex).build());
while (cursor.hasNext()) {
batchKeys.add(cursor.next());
if (batchKeys.size() == 1000) {
deletedCount += redisConnection.del(getKeys(batchKeys));
batchKeys.clear();
}
}
// delete any left-over keys if some were added to the batch but never reached 1000
if (batchKeys.size() > 0) {
deletedCount += redisConnection.del(getKeys(batchKeys));
batchKeys.clear();
}
return deletedCount;
});
}
public List<String> findKeysForPage(String patternKey, int pageNum, int pageSize) {
Set<String> execute = redisTemplate.execute(new RedisCallback<Set<String>>() {
@Override
public Set<String> doInRedis(RedisConnection connection) throws DataAccessException {
Set<String> binaryKeys = new HashSet<>();
Cursor<byte[]> cursor = connection
.scan(new ScanOptions.ScanOptionsBuilder().match(patternKey).count(1000).build());
int tmpIndex = 0;
int startIndex = (pageNum - 1) * pageSize;
int end = pageNum * pageSize;
while (cursor.hasNext()) {
if (tmpIndex >= startIndex && tmpIndex < end) {
binaryKeys.add(new String(cursor.next()));
tmpIndex++;
continue;
}
// 获取到满足条件的数据后,就可以退出了
if (tmpIndex >= end) {
break;
}
tmpIndex++;
cursor.next();
}
connection.close();
return binaryKeys;
}
});
List<String> result = new ArrayList<String>(pageSize);
result.addAll(execute);
return result;
}
@Test
public void testScanCommand() {
RedisConnection connection = Objects.requireNonNull(stringRedisTemplate.getConnectionFactory()).getConnection();
Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().match("*").count(Integer.MAX_VALUE).build());
while (cursor.hasNext()) {
byte[] next = cursor.next();
log.info(new String(next));
}
}
/**
* @Description: 从Redis获取用户点赞数据
* @Param: []
* @return: java.util.List<com.zzx.model.pojo.UserLike>
* @Author: Tyson
* @Date: 2020/5/30/0030 11:37
*/
public List<UserLike> getUserLikeFromRedis() {
List<UserLike> userLikeList = new ArrayList<>();
try {
Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(RedisConfig.MAP_USER_LIKE_KEY, ScanOptions.NONE);
while (cursor.hasNext()) {
Map.Entry<Object, Object> entry = cursor.next();
String key = (String)entry.getKey();
//拆分key,blogId::userId
String[] keyArr = key.split(RedisConfig.REDIS_LIKE_MID);
int blogId = Integer.parseInt(keyArr[0]);
int userId= Integer.parseInt(keyArr[1]);
int status = Integer.parseInt((String)entry.getValue());
UserLike userLike = new UserLike(blogId, userId, status);
userLikeList.add(userLike);
//从redis删除key
redisTemplate.opsForHash().delete(RedisConfig.MAP_USER_LIKE_KEY, key);
}
cursor.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return userLikeList;
}
/**
* 分页获取指定格式key,使用 scan 命令代替 keys 命令,在大数据量的情况下可以提高查询效率
*
* @param patternKey key格式
* @param currentPage 当前页码
* @param pageSize 每页条数
* @return 分页获取指定格式key
*/
public PageResult<String> findKeysForPage(String patternKey, int currentPage, 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 = Lists.newArrayList();
long tmpIndex = 0;
int startIndex = (currentPage - 1) * pageSize;
int end = currentPage * pageSize;
while (cursor.hasNext()) {
String key = new String(cursor.next());
if (tmpIndex >= startIndex && tmpIndex < end) {
result.add(key);
}
tmpIndex++;
}
try {
cursor.close();
RedisConnectionUtils.releaseConnection(rc, factory);
} catch (Exception e) {
log.warn("Redis连接关闭异常,", e);
}
return new PageResult<>(result, tmpIndex);
}
/**
* 分页查询 key
* @param patternKey key
* @param page 页码
* @param size 每页数目
* @return /
*/
public List<String> findKeysForPage(String patternKey, int page, int size) {
ScanOptions options = ScanOptions.scanOptions().match(patternKey).build();
RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
RedisConnection rc = Objects.requireNonNull(factory).getConnection();
Cursor<byte[]> cursor = rc.scan(options);
List<String> result = new ArrayList<>(size);
int tmpIndex = 0;
int fromIndex = page * size;
int toIndex = page * size + size;
while (cursor.hasNext()) {
if (tmpIndex >= fromIndex && tmpIndex < toIndex) {
result.add(new String(cursor.next()));
tmpIndex++;
continue;
}
// 获取到满足条件的数据后,就可以退出了
if(tmpIndex >=toIndex) {
break;
}
tmpIndex++;
cursor.next();
}
try {
RedisConnectionUtils.releaseConnection(rc, factory);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 分页获取指定格式key,使用 scan 命令代替 keys 命令,在大数据量的情况下可以提高查询效率
*
* @param patternKey key格式
* @param currentPage 当前页码
* @param pageSize 每页条数
* @return 分页获取指定格式key
*/
public PageResult<String> findKeysForPage(String patternKey, int currentPage, 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 = Lists.newArrayList();
long tmpIndex = 0;
int startIndex = (currentPage - 1) * pageSize;
int end = currentPage * pageSize;
while (cursor.hasNext()) {
String key = new String(cursor.next());
if (tmpIndex >= startIndex && tmpIndex < end) {
result.add(key);
}
tmpIndex++;
}
try {
cursor.close();
RedisConnectionUtils.releaseConnection(rc, factory);
} catch (Exception e) {
log.warn("Redis连接关闭异常,", e);
}
return new PageResult<>(result, tmpIndex);
}
/**
* 分页获取指定格式key,使用 scan 命令代替 keys 命令,在大数据量的情况下可以提高查询效率
*
* @param patternKey key格式
* @param currentPage 当前页码
* @param pageSize 每页条数
* @return 分页获取指定格式key
*/
public PageResult<String> findKeysForPage(String patternKey, int currentPage, 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 = Lists.newArrayList();
long tmpIndex = 0;
int startIndex = (currentPage - 1) * pageSize;
int end = currentPage * pageSize;
while (cursor.hasNext()) {
String key = new String(cursor.next());
if (tmpIndex >= startIndex && tmpIndex < end) {
result.add(key);
}
tmpIndex++;
}
try {
cursor.close();
RedisConnectionUtils.releaseConnection(rc, factory);
} catch (Exception e) {
log.warn("Redis连接关闭异常,", e);
}
return new PageResult<>(result, tmpIndex);
}
@Override
public Cursor<Entry<HK, HV>> scan(K key, final ScanOptions options) {
final byte[] rawKey = rawKey(key);
return execute(new RedisCallback<Cursor<Map.Entry<HK, HV>>>() {
@Override
public Cursor<Entry<HK, HV>> doInRedis(RedisConnection connection) throws DataAccessException {
return new ConvertingCursor<Map.Entry<byte[], byte[]>, Map.Entry<HK, HV>>(connection.hScan(rawKey, options),
new Converter<Map.Entry<byte[], byte[]>, Map.Entry<HK, HV>>() {
@Override
public Entry<HK, HV> convert(final Entry<byte[], byte[]> source) {
return new Map.Entry<HK, HV>() {
@Override
public HK getKey() {
return deserializeHashKey(source.getKey());
}
@Override
public HV getValue() {
return deserializeHashValue(source.getValue());
}
@Override
public HV setValue(HV value) {
throw new UnsupportedOperationException("Values cannot be set when scanning through entries.");
}
};
}
});
}
}, true);
}
/**
* Uses {@code SCAN} command for loading all matching keys. <br />
* {@code SCAN} uses a cursor on server side returning only a subset of the available data with the possibility to
* ripple load further elements using the cursors position. <br />
* All keys will be loaded using <strong>multiple</strong> operations.
*/
@Test
public void iterateOverKeysMatchingPrefixUsingScanCommand() {
generateRandomKeys(1000);
Cursor<byte[]> cursor = this.connection.scan(ScanOptions.scanOptions().match(KEY_PATTERN).build());
printKeys(cursor);
}
@Test
public void testZScan() {
connection.zAdd("key".getBytes(), 1, "value1".getBytes());
connection.zAdd("key".getBytes(), 2, "value2".getBytes());
Cursor<RedisZSetCommands.Tuple> t = connection.zScan("key".getBytes(), ScanOptions.scanOptions().build());
assertThat(t.hasNext()).isTrue();
assertThat(t.next().getValue()).isEqualTo("value1".getBytes());
assertThat(t.hasNext()).isTrue();
assertThat(t.next().getValue()).isEqualTo("value2".getBytes());
}
@Test
public void testZScan() {
connection.zAdd("key".getBytes(), 1, "value1".getBytes());
connection.zAdd("key".getBytes(), 2, "value2".getBytes());
Cursor<RedisZSetCommands.Tuple> t = connection.zScan("key".getBytes(), ScanOptions.scanOptions().build());
assertThat(t.hasNext()).isTrue();
assertThat(t.next().getValue()).isEqualTo("value1".getBytes());
assertThat(t.hasNext()).isTrue();
assertThat(t.next().getValue()).isEqualTo("value2".getBytes());
}
@Test
public void testZScan() {
connection.zAdd("key".getBytes(), 1, "value1".getBytes());
connection.zAdd("key".getBytes(), 2, "value2".getBytes());
Cursor<RedisZSetCommands.Tuple> t = connection.zScan("key".getBytes(), ScanOptions.scanOptions().build());
assertThat(t.hasNext()).isTrue();
assertThat(t.next().getValue()).isEqualTo("value1".getBytes());
assertThat(t.hasNext()).isTrue();
assertThat(t.next().getValue()).isEqualTo("value2".getBytes());
}
@Override
public Cursor<byte[]> scan(ScanOptions options) {
return redisConnection.scan(options);
}
@Override
public Cursor<byte[]> sScan(byte[] key, ScanOptions options) {
return redisConnection.sScan(key, options);
}
@Override
public Cursor<Tuple> zScan(byte[] key, ScanOptions options) {
return redisConnection.zScan(key, options);
}
@Override
public Cursor<Map.Entry<byte[], byte[]>> hScan(byte[] key, ScanOptions options) {
return redisConnection.hScan(key, options);
}
@Override
public Cursor<byte[]> scan(ScanOptions options) {
return helper.doInScope(RedisCommand.SCAN, () -> connection.scan(options));
}
@Override
public Cursor<byte[]> sScan(byte[] key, ScanOptions options) {
return helper.doInScope(RedisCommand.SSCAN, key, () -> connection.sScan(key, options));
}
@Override
public Cursor<Tuple> zScan(byte[] key, ScanOptions options) {
return helper.doInScope(RedisCommand.ZSCAN, key, () -> connection.zScan(key, options));
}
@Override
public Cursor<Entry<byte[], byte[]>> hScan(byte[] key, ScanOptions options) {
return helper.doInScope(RedisCommand.HSCAN, key, () -> connection.hScan(key, options));
}
@Override
public Cursor<byte[]> scan(RedisClusterNode node, ScanOptions options) {
return helper.doInScope(SCAN, () -> connection.scan(node, options));
}
@Override
public Cursor<byte[]> scan(ScanOptions options) {
return helper.doInScope(RedisCommand.SCAN, () -> connection.scan(options));
}
@Override
public Cursor<byte[]> sScan(byte[] key, ScanOptions options) {
return helper.doInScope(RedisCommand.SSCAN, key, () -> connection.sScan(key, options));
}