Skip to content

Commit 14a1419

Browse files
lc77254mp911de
authored andcommitted
Support scan in RedisTemplate.
Closes #2260 Original pull request: #2263.
1 parent 2a1be5d commit 14a1419

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

src/main/java/org/springframework/data/redis/core/RedisOperations.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
* @author Mark Paluch
4646
* @author ihaohong
4747
* @author Todd Merrill
48+
* @author Chen Li
4849
*/
4950
public interface RedisOperations<K, V> {
5051

@@ -259,6 +260,16 @@ <T> T execute(RedisScript<T> script, RedisSerializer<?> argsSerializer, RedisSer
259260
@Nullable
260261
Set<K> keys(K pattern);
261262

263+
/**
264+
* Use a {@link Cursor} to iterate over keys. <br />
265+
* <strong>Important:</strong> Call {@link Cursor#close()} when done to avoid resource leak.
266+
*
267+
* @param options must not be {@literal null}.
268+
* @return never {@literal null}.
269+
* @see <a href="https://redis.io/commands/scan">Redis Documentation: SCAN</a>
270+
*/
271+
Cursor<K> scan(ScanOptions options);
272+
262273
/**
263274
* Return a random key from the keyspace.
264275
*

src/main/java/org/springframework/data/redis/core/RedisTemplate.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
* @author Mark Paluch
8484
* @author Denis Zavedeev
8585
* @author ihaohong
86+
* @author Chen Li
8687
* @param <K> the Redis key type against which the template works (usually a String)
8788
* @param <V> the Redis value type against which the template works
8889
* @see StringRedisTemplate
@@ -897,6 +898,19 @@ public Set<K> keys(K pattern) {
897898
return keySerializer != null ? SerializationUtils.deserialize(rawKeys, keySerializer) : (Set<K>) rawKeys;
898899
}
899900

901+
/*
902+
* (non-Javadoc)
903+
* @see org.springframework.data.redis.core.RedisOperations#scan(java.lang.Object)
904+
*/
905+
@Override
906+
public Cursor<K> scan(ScanOptions options) {
907+
Assert.notNull(options, "ScanOptions must not be null!");
908+
909+
return executeWithStickyConnection(
910+
(RedisCallback<Cursor<K>>) connection -> new ConvertingCursor<>(connection.scan(options),
911+
this::deserializeKey));
912+
}
913+
900914
/*
901915
* (non-Javadoc)
902916
* @see org.springframework.data.redis.core.RedisOperations#persist(java.lang.Object)

src/test/java/org/springframework/data/redis/core/RedisTemplateIntegrationTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
* @author Mark Paluch
6363
* @author ihaohong
6464
* @author Hendrik Duerkop
65+
* @author Chen Li
6566
*/
6667
@MethodSource("testParams")
6768
public class RedisTemplateIntegrationTests<K, V> {
@@ -126,6 +127,22 @@ void testKeys() throws Exception {
126127
assertThat(redisTemplate.keys(keyPattern)).isNotNull();
127128
}
128129

130+
@ParameterizedRedisTest // GH-2260
131+
void testScan() {
132+
K key1 = keyFactory.instance();
133+
V value1 = valueFactory.instance();
134+
assumeThat(key1 instanceof String || key1 instanceof byte[]).isTrue();
135+
redisTemplate.opsForValue().set(key1, value1);
136+
Cursor<K> cursor = redisTemplate.scan(ScanOptions.scanOptions().count(1).build());
137+
long count = 0;
138+
while (cursor.hasNext()) {
139+
assertThat(cursor.next()).isEqualTo(key1);
140+
count++;
141+
}
142+
cursor.close();
143+
assertThat(count).isEqualTo(1);
144+
}
145+
129146
@SuppressWarnings("rawtypes")
130147
@ParameterizedRedisTest
131148
void testTemplateNotInitialized() throws Exception {

0 commit comments

Comments
 (0)