java-redis集合数据操作示例(三)

 redis 系列博文,redis 连接管理类的代码请跳转查看《java-redis 字符类数据操作示例 (一)》。

一、集合类型缓存测试类

public class SetTest {
    /**
     * 主测试方案
     */
    @Test
    public void test() {
        RedisUtil.instance.run(conn -> oper(conn));
        Assert.assertTrue(true);}
    /**
     * 测试用的 key
     */
    private final String _key = "simm-set";
    /**
     * 字符串操作
     * 
     * @param conn
     */
    private void oper(ShardedJedis conn) {
        System.out.println(MessageFormat.format("key[{0}] 存在:{1}", _key,conn.exists(_key)));
        // 集合数据初始化
        String[] arr= "AA,AB,AC,AD,AE,AF,AG,BA,BB,BC,BD,BE,BF,BG".split(",");
        conn.sadd(_key, arr);
        print(conn);
        //1. 查询元素
        //指定个数 count 在 redis 服务中默认值为 10 
        ScanResult<String> result = conn.sscan(_key, "0",new ScanParams().match("*").count(2));
        String cursor = result.getStringCursor();
        System.out.println(MessageFormat.format("游标位置:{0}", cursor));
        print(result.getResult());
        //匹配内容
        result = conn.sscan(_key, "0",new ScanParams().match("A*"));
        print(result.getResult());
        result = conn.sscan(_key, "0",new ScanParams().match("A*").count(100));
        print(result.getResult());
        //2. 集合元素删除方法 
        //2.1. 移除
        Long effected = conn.srem(_key, "AE","BG","HI");//移除 CGH。
        System.out.println(MessageFormat.format("成功移除 {0} 个元素", effected));
        print(conn);
        //2.2. 从集合中弹出一个元素
        String pop = conn.spop(_key);
        System.out.println(MessageFormat.format("POP: {0}", pop));
        print(conn);
        //3. 判断元素是否存在
        System.out.println(MessageFormat.format("A 是集合中的元素? {0}", conn.sismember(_key, "AA")));
        System.out.println(MessageFormat.format("J 是集合中的元素? {0}", conn.sismember(_key, "JQ")));
    conn.expire(_key, </span>1); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置改key值1s后过期,过期后redis自动清理该缓存</span>
    System.out.println(MessageFormat.format("key[{0}]存在:{1} "<span style="color: rgba(0, 0, 0, 1)">, _key,conn.exists(_key)));
}

</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> print(List&lt;String&gt;<span style="color: rgba(0, 0, 0, 1)"> list){
    System.out.print(MessageFormat.format(</span>"scan输出,长度[{1}]:"<span style="color: rgba(0, 0, 0, 1)">, _key,list.size()));
    </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (String str : list) {
        System.out.print(MessageFormat.format(</span>"{0} "<span style="color: rgba(0, 0, 0, 1)">, str));
    }
    System.out.println();
}

</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> print(ShardedJedis conn){
    System.out.print(MessageFormat.format(</span>"{0}元素输出,长度[{1}]:"<span style="color: rgba(0, 0, 0, 1)">, _key,conn.scard(_key)));
    Set</span>&lt;String&gt; list =<span style="color: rgba(0, 0, 0, 1)"> conn.smembers(_key);
    </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (String str : list) {
        System.out.print(MessageFormat.format(</span>"{0} "<span style="color: rgba(0, 0, 0, 1)">, str));
    }
    System.out.println();
}

}

二、结果输出

  

三、关于sscan命令

  

  match 参数用于过滤,count 参数用于限制一次迭代返回的集合数目。这个值默认是 10。我测试了两种情况,集合元素个数少于 10 以及大于 10。后面给出测试的结果。测试过这个 sscan 方法后,有点懵逼,网上查找别人的分享,好像也是懵逼的多。显示设置一次迭代的个数,是否能够生效,还受到 set 元素总个数是否超过 10 的影响。这块的实现让人费解。就测试后来看,当数据量不是很大,想正确的一次查询所有匹配项的话,请设置一个较大的 count 参数,这样能保证数据量从少到多的过程中都不会出问题。

  1、初始化集合元素为 7 个

  // 集合数据初始化
        String[] arr= "AA,AB,AC,AD,AE,AF,AG".split(",");
        conn.sadd(_key, arr);
        print(conn);
        //1. 查询元素
        //指定个数 count 在 redis 服务中默认值为 10 
        ScanResult<String> result = conn.sscan(_key, "0",new ScanParams().match("A*").count(2));
        String cursor = result.getStringCursor();
        System.out.println(MessageFormat.format("游标位置:{0}", cursor));
        print(result.getResult());
        //匹配内容
        result = conn.sscan(_key, "0",new ScanParams().match("A*"));
        print(result.getResult());
        result = conn.sscan(_key, "0",new ScanParams().match("A*").count(100));
        print(result.getResult());

    测试 3 种场景,情况如下

    •  match("A*").count(2):查询以 A 开头的元素,限定一次迭代 2 个元素。结果返回了 3 个数据。设置一次迭代 2 个元素,结果返回元素还大于设置的迭代量,卧槽,蛋疼的结果;
    •  match("A*"):不显示指定迭代个数,结果返回了所有的匹配项;
    •  match("A*").count(100):指定一次迭代上限为 100,结果也返回了所有的匹配项。

  2、初始化集合元素为 14 个

        // 集合数据初始化
        String[] arr= "AA,AB,AC,AD,AE,AF,AG,BA,BB,BC,BD,BE,BF,BG".split(",");
        conn.sadd(_key, arr);
        print(conn);
        //1. 查询元素
        //指定个数 count 在 redis 服务中默认值为 10 
        ScanResult<String> result = conn.sscan(_key, "0",new ScanParams().match("A*").count(2));
        String cursor = result.getStringCursor();
        System.out.println(MessageFormat.format("游标位置:{0}", cursor));
        print(result.getResult());
        //匹配内容
        result = conn.sscan(_key, "0",new ScanParams().match("A*"));
        print(result.getResult());
        result = conn.sscan(_key, "0",new ScanParams().match("A*").count(100));
        print(result.getResult());

    测试 3 种场景,情况如下

    •  match("A*").count(2):查询以 A 开头的元素,限定一次迭代 2 个元素。结果返回为空。可以理解为这一次的 2 个迭代元素均不符合过滤条件;
    •  match("A*"):不显示指定迭代个数,结果返回了 4 个匹配项。这样看默认的 10 个一批迭代的设置起作用了;
    •  match("A*").count(100):指定一次迭代上限为 100,结果返回了所有的匹配项。看来想一次正确返回所有匹配项,只能直接设置一个较大的迭代值了。