redisTemplate的hscan方法中为何不需要指定游标开始地址的原因

redis的hscan写法``

HSCAN key cursor [MATCH pattern] [COUNT count]

这里明明是有cursor参数,为何spring的redistemplate客户端中不提供该起始游标的参数?

		RedisTemplate rt;
		rt.opsForHash().scan("key", ScanOptions.scanOptions().count(100).match("*").build());

ScanOptions该方法只有两个参数:

public class ScanOptions {

	/**
	 * Constant to apply default {@link ScanOptions} without setting a limit or matching a pattern.
	 */
	public static ScanOptions NONE = new ScanOptions(null, null);

	private final @Nullable Long count;
	private final @Nullable String pattern;

那么问题来了,开始的游标的参数在哪里呢?于是乎有人就这样误用这个方法了
错误使用示例:

		RedisTemplate rt;
		rt.opsForHash().scan("key", ScanOptions.scanOptions().count(Integer.MAX_VALUE).match("*").build());

一次拿完所有的的值,这样使用这个方法的意义就没有了,这个方法的本意是分批小段遍历,这样一次取出来和直接hkeys全部没有任何区别,时间复杂度都是O(n),那这个方法的count参数应该传什么值?答案就是一般传某一分页大小的值(其实这个值是不能用来分页的,因为这个值只是个大概值,redis不保证传回的数量是多少,这是另一个问题,不在这里引申出去了).
那疑问又来了,如果count传分页大小比如100,那他是怎么获取到这个hash结构下所有的field的?
答案是redisTemplate帮我们封装好了。其实你调用以下代码的时候

		Cursor cursor = rt.opsForHash().scan("key", ScanOptions.scanOptions().count(Integer.MAX_VALUE).match("*").build());
		while(cursor.hasNext()){
			cursor.next()
		}

驱动第二次调用底层原生scan代码的方法是cursor.hasNext,当发现上一次底层原生scan返回的值已经遍及完的时候,他会再次执行scan方法去redis获取数据,而起始的游标Id就是上一次scan返回的游标值,直到遍历结束,这样就达到了分批遍历的目的

你可能感兴趣的:(redis,redis,java)