zoukankan      html  css  js  c++  java
  • redis使用

    https://www.cnblogs.com/zeng1994/p/03303c805731afc9aa9c60dbbd32a323.html

    1 redisTemplate  模板

    Spring封装了一个比较强大的模板,也就是redisTemplate,方便在开发的时候操作Redis缓存。在Redis中可以存储String、List、Set、Hash、Zset

    List  Redis中的List为简单的字符串列表,常见的有下面几种操作。

    1) hasKey  判断一个键是否存在,只需要调用hasKey就可以了。假设这个Key是test,具体用法如下

    if (redisTemplate.hasKey("test")) {
        System.out.println("存在");
    } else {
        System.out.println("不存在");
    }

    2) range 该函数用于从redis缓存中获取指定区间的数据。具体用法如下

    if (redisTemplate.hasKey("test")) {
        // 该键的值为 [4, 3, 2, 1]
        System.out.println(redisTemplate.opsForList().range("test", 0, 0)); // [4]
        System.out.println(redisTemplate.opsForList().range("test", 0, 1)); // [4, 3]
        System.out.println(redisTemplate.opsForList().range("test", 0, 2)); // [4, 3, 2]
        System.out.println(redisTemplate.opsForList().range("test", 0, 3)); // [4, 3, 2, 1]
        System.out.println(redisTemplate.opsForList().range("test", 0, 4)); // [4, 3, 2, 1]
        System.out.println(redisTemplate.opsForList().range("test", 0, 5)); // [4, 3, 2, 1]
    
        System.out.println(redisTemplate.opsForList().range("test", 0, -1)); // [4, 3, 2, 1] 如果结束位是-1, 则表示取所有的值
    }

    3) delete 删除某个键

    List<String> test = new ArrayList<>();
    test.add("1");
    test.add("2");
    test.add("3");
    test.add("4");
    
    redisTemplate.opsForList().rightPushAll("test", test);
    System.out.println(redisTemplate.opsForList().range("test", 0, -1)); // [1, 2, 3, 4]
    redisTemplate.delete("test");
    System.out.println(redisTemplate.opsForList().range("test", 0, -1)); // []

    4) size 获取该键的集合长度

    List<String> test = new ArrayList<>();
    test.add("1");
    test.add("2");
    test.add("3");
    test.add("4");
    
    redisTemplate.opsForList().rightPushAll("test", test);
    System.out.println(redisTemplate.opsForList().size("test")); // 4

    5) leftPush

    取数据总是从左边取,但是存数据可以从左也可以从右。左就是leftPush,右就是rightPush

    for (int i = 0; i < 4; i++) {
        Integer value = i + 1;
        redisTemplate.opsForList().leftPush("test", value.toString());
        System.out.println(redisTemplate.opsForList().range("test", 0, -1));
    }

    结果
    [1]
    [2, 1]
    [3, 2, 1]
    [4, 3, 2, 1]
     

     6)leftPushAll 基本和leftPush一样,只不过是一次性的将List入栈。

    List<String> test = new ArrayList<>();
    test.add("1");
    test.add("2");
    test.add("3");
    test.add("4");
    redisTemplate.opsForList().leftPushAll("test", test);
    System.out.println(redisTemplate.opsForList().range("test", 0, -1)); // [4, 3, 2, 1]

    也可以
    redisTemplate.opsForList().leftPushAll("test", "1", "2", "3", "4");
    System.out.println(redisTemplate.opsForList().range("test", 0, -1)); // [4, 3, 2, 1]
     

     7) leftPushIfPresent

    leftPush是同样的操作,唯一的不同是,当且仅当key存在时,才会更新key的值。如果key不存在则不会对数据进行任何操作。

    redisTemplate.delete("test");
    
    redisTemplate.opsForList().leftPushIfPresent("test", "1");
    redisTemplate.opsForList().leftPushIfPresent("test", "2");
    System.out.println(redisTemplate.opsForList().range("test", 0, -1)); // []

    8)  leftPop 该函数用于移除上面我们抽象的容器中的最左边的一个元素。

    List<String> test = new ArrayList<>();
    test.add("1");
    test.add("2");
    test.add("3");
    test.add("4");
    redisTemplate.opsForList().rightPushAll("test", test);
    
    redisTemplate.opsForList().leftPop("test"); // [2, 3, 4]
    redisTemplate.opsForList().leftPop("test"); // [3, 4]
    redisTemplate.opsForList().leftPop("test"); // [4]
    redisTemplate.opsForList().leftPop("test"); // []
    redisTemplate.opsForList().leftPop("test"); // []

    值得注意的是,当返回为空后,在redis中这个key也不复存在了。如果此时再调用leftPushIfPresent,是无法再添加数据的。有代码有真相。

    List<String> test = new ArrayList<>();
    test.add("1");
    test.add("2");
    test.add("3");
    test.add("4");
    redisTemplate.opsForList().rightPushAll("test", test);
    
    redisTemplate.opsForList().leftPop("test"); // [2, 3, 4]
    redisTemplate.opsForList().leftPop("test"); // [3, 4]
    redisTemplate.opsForList().leftPop("test"); // [4]
    redisTemplate.opsForList().leftPop("test"); // []
    redisTemplate.opsForList().leftPop("test"); // []
    
    redisTemplate.opsForList().leftPushIfPresent("test", "1"); // []
    redisTemplate.opsForList().leftPushIfPresent("test", "1"); // []

    9)rightPush

    用法
    for
    (int i = 0; i < 4; i++) { Integer value = i + 1; redisTemplate.opsForList().leftPush("test", value.toString()); System.out.println(redisTemplate.opsForList().range("test", 0, -1)); }
    结果
    [1]
    [1, 2]
    [1, 2, 3]
    [1, 2, 3, 4]
     

    10) rightPushAll

    同rightPush,一次性将List存入
    List<String> test = new ArrayList<>();
    test.add("1");
    test.add("2");
    test.add("3");
    test.add("4");
    redisTemplate.opsForList().rightPushAll("test", test);
    System.out.println(redisTemplate.opsForList().range("test", 0, -1)); // [1, 2, 3, 4]
    也可以
    redisTemplate.opsForList().rightPushAll("test", "1", "2", "3", "4");
    System.out.println(redisTemplate.opsForList().range("test", 0, -1)); // [1, 2, 3, 4]
     

    11)  rightPushIfPresent

    rightPush是同样的操作,唯一的不同是,当且仅当key存在时,才会更新key的值。如果key不存在则不会对数据进行任何操作。

    redisTemplate.delete("test");
    
    redisTemplate.opsForList().rightPushIfPresent("test", "1");
    redisTemplate.opsForList().rightPushIfPresent("test", "2");
    System.out.println(redisTemplate.opsForList().range("test", 0, -1)); // []

    12) rightPop  

    该函数用于移除上面我们抽象的容器中的最右边的一个元素。

    List<String> test = new ArrayList<>();
    test.add("1");
    test.add("2");
    test.add("3");
    test.add("4");
    redisTemplate.opsForList().rightPushAll("test", test);
    
    redisTemplate.opsForList().rightPop("test"); // [1, 2, 3]
    redisTemplate.opsForList().rightPop("test"); // [1, 2]
    redisTemplate.opsForList().rightPop("test"); // [1]
    redisTemplate.opsForList().rightPop("test"); // []
    redisTemplate.opsForList().rightPop("test"); // []
    leftPop一样,返回空之后,再调用rightPushIfPresent,是无法再添加数据的。

    13) index

    获取list中指定位置的元素。
    if (redisTemplate.hasKey("test")) {
        // 该键的值为 [1, 2, 3, 4]
        System.out.println(redisTemplate.opsForList().index("test", -1)); // 4
        System.out.println(redisTemplate.opsForList().index("test", 0)); // 1
        System.out.println(redisTemplate.opsForList().index("test", 1)); // 2
        System.out.println(redisTemplate.opsForList().index("test", 2)); // 3
        System.out.println(redisTemplate.opsForList().index("test", 3)); // 4
        System.out.println(redisTemplate.opsForList().index("test", 4)); // null
        System.out.println(redisTemplate.opsForList().index("test", 5)); // null
    }
    值得注意的有两点。一个是如果下标是-1的话,则会返回List最后一个元素,另一个如果数组下标越界,则会返回null

    14) trim

    用于截取指定区间的元素,可能你会理解成与range是一样的作用。看了下面的代码之后应该就会立刻理解。

    List<String> test = new ArrayList<>();
    test.add("1");
    test.add("2");
    test.add("3");
    test.add("4");
    redisTemplate.opsForList().rightPushAll("test", test); // [1, 2, 3, 4]
    
    redisTemplate.opsForList().trim("test", 0, 2); // [1, 2, 3]
    其实作用完全不一样。range是获取指定区间内的数据,而trim是留下指定区间的数据,删除不在区间的所有数据。trimvoid,不会返回任何数据。

    15) remove

    用于移除键中指定的元素。接受3个参数,分别是缓存的键名,计数事件,要移除的值。计数事件可以传入的有三个值,分别是-101

    -1代表从存储容器的最右边开始,删除一个与要移除的值匹配的数据;0代表删除所有与传入值匹配的数据;1代表从存储容器的最左边开始,删除一个与要移除的值匹配的数据。

    List<String> test = new ArrayList<>();
    test.add("1");
    test.add("2");
    test.add("3");
    test.add("4");
    test.add("4");
    test.add("3");
    test.add("2");
    test.add("1");
    
    redisTemplate.opsForList().rightPushAll("test", test); // [1, 2, 3, 4, 4, 3, 2, 1]
    
    // 当计数事件是-1、传入值是1时
    redisTemplate.opsForList().remove("test", -1, "1"); // [1, 2, 3, 4, 4, 3, 2]
    
    // 当计数事件是1,传入值是1时
    redisTemplate.opsForList().remove("test", 1, "1"); // [2, 3, 4, 4, 3, 2]
    
    // 当计数事件是0,传入值是4时
    redisTemplate.opsForList().remove("test", 0, "4"); // [2, 3, 3, 2]

     16 rightPopAndLeftPush

    该函数用于操作两个键之间的数据,接受两个参数,分别是源key、目标key。该函数会将源key进行rightPop,再将返回的值,作为输入参数,在目标key上进行leftPush。具体代码如下。

    List<String> test = new ArrayList<>();
    test.add("1");
    test.add("2");
    test.add("3");
    test.add("4");
    
    List<String> test2 = new ArrayList<>();
    test2.add("1");
    test2.add("2");
    test2.add("3");
    
    redisTemplate.opsForList().rightPushAll("test", test); // [1, 2, 3, 4]
    redisTemplate.opsForList().rightPushAll("test2", test2); // [1, 2, 3]
    
    redisTemplate.opsForList().rightPopAndLeftPush("test", "test2");
    
    System.out.println(redisTemplate.opsForList().range("test", 0, -1)); // [1, 2, 3]
    System.out.println(redisTemplate.opsForList().range("test2", 0, -1)); // [4, 1, 2, 3]

     Hash

    存储类型为hash其实很好理解。在上述的List中,一个redis的Key可以理解为一个List,而在Hash中,一个redis的Key可以理解为一个HashMap。

    1)put

    用于写入数据。

    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    
    redisTemplate.opsForHash().put("test", "map", list.toString()); // [1, 2, 3, 4]
    redisTemplate.opsForHash().put("test", "isAdmin", true); // true

    2) putAll

    用于一次性向一个Hash键中添加多个key。

    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    List<String> list2 = new ArrayList<>();
    list2.add("5");
    list2.add("6");
    list2.add("7");
    list2.add("8");
    Map<String, String> valueMap = new HashMap<>();
    valueMap.put("map1", list.toString());
    valueMap.put("map2", list2.toString());
    
    redisTemplate.opsForHash().putAll("test", valueMap); // {map2=[5, 6, 7, 8], map1=[1, 2, 3, 4]}

    3) putIfAbsent

    用于向一个Hash键中写入数据。当key在Hash键中已经存在时,则不会写入任何数据,只有在Hash键中不存在这个key时,才会写入数据。

    同时,如果连这个Hash键都不存在,redisTemplate会新建一个Hash键,再写入key。

    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    redisTemplate.opsForHash().putIfAbsent("test", "map", list.toString());
    System.out.println(redisTemplate.opsForHash().entries("test")); // {map=[1, 2, 3, 4]}

    4) get

    用于获取数据。

    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    
    redisTemplate.opsForHash().put("test", "map", list.toString());
    redisTemplate.opsForHash().put("test", "isAdmin", true);
    
    System.out.println(redisTemplate.opsForHash().get("test", "map")); // [1, 2, 3, 4]
    System.out.println(redisTemplate.opsForHash().get("test", "isAdmin")); // true
    
    Boolean bool = (Boolean) redisTemplate.opsForHash().get("test", "isAdmin");
    System.out.println(bool); // true
    
    String str = redisTemplate.opsForHash().get("test", "map").toString();
    List<String> array = JSONArray.parseArray(str, String.class);
    System.out.println(array.size()); // 4

    值得注意的是,使用get函数获取的数据都是Object类型。

    所以需要使用类型与上述例子中的布尔类型的话,则需要强制转换一次。List类型则可以使用fastjson这种工具来进行转换。转换的例子已列举在上述代码中。

    5) delete

    用于删除一个Hash键中的key。可以理解为删除一个map中的某个key。

    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    List<String> list2 = new ArrayList<>();
    list2.add("5");
    list2.add("6");
    list2.add("7");
    list2.add("8");
    Map<String, String> valueMap = new HashMap<>();
    valueMap.put("map1", list.toString());
    valueMap.put("map2", list2.toString());
    
    redisTemplate.opsForHash().putAll("test", valueMap); // {map2=[5, 6, 7, 8], map1=[1, 2, 3, 4]}
    redisTemplate.opsForHash().delete("test", "map1"); // {map2=[5, 6, 7, 8]}

    6) values

    用于获取一个Hash类型的键的所有值。

    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    
    redisTemplate.opsForHash().put("test", "map", list.toString());
    redisTemplate.opsForHash().put("test", "isAdmin", true);
    
    System.out.println(redisTemplate.opsForHash().values("test")); // [[1, 2, 3, 4], true]

    7) entries

    用于以Map的格式获取一个Hash键的所有值。

    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    
    redisTemplate.opsForHash().put("test", "map", list.toString());
    redisTemplate.opsForHash().put("test", "isAdmin", true);
    
    Map<String, String> map = redisTemplate.opsForHash().entries("test");
    System.out.println(map.get("map")); // [1, 2, 3, 4]
    System.out.println(map.get("map") instanceof String); // true
    System.out.println(redisTemplate.opsForHash().entries("test")); // {a=[1, 2, 3, 4], isAdmin=true}

    8) hasKey

    用于获取一个Hash键中是否含有某个键。

    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    
    redisTemplate.opsForHash().put("test", "map", list.toString());
    redisTemplate.opsForHash().put("test", "isAdmin", true);
    
    System.out.println(redisTemplate.opsForHash().hasKey("test", "map")); // true
    System.out.println(redisTemplate.opsForHash().hasKey("test", "b")); // false
    System.out.println(redisTemplate.opsForHash().hasKey("test", "isAdmin")); // true

    9) keys

    用于获取一个Hash键中所有的键。

    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    
    redisTemplate.opsForHash().put("test", "map", list.toString());
    redisTemplate.opsForHash().put("test", "isAdmin", true);
    
    System.out.println(redisTemplate.opsForHash().keys("test")); // [a, isAdmin]

    10 size

    用于获取一个Hash键中包含的键的数量。

    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    
    redisTemplate.opsForHash().put("test", "map", list.toString());
    redisTemplate.opsForHash().put("test", "isAdmin", true);
    
    System.out.println(redisTemplate.opsForHash().size("test")); // 2

    11) increment

    用于让一个Hash键中的某个key,根据传入的值进行累加。传入的数值只能是double或者long,不接受浮点型

    redisTemplate.opsForHash().increment("test", "a", 3);
    redisTemplate.opsForHash().increment("test", "a", -3);
    redisTemplate.opsForHash().increment("test", "a", 1);
    redisTemplate.opsForHash().increment("test", "a", 0);
    
    System.out.println(redisTemplate.opsForHash().entries("test")); // {a=1}

    12 multiGet

    用于批量的获取一个Hash键中多个key的值。

    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    List<String> list2 = new ArrayList<>();
    list2.add("5");
    list2.add("6");
    list2.add("7");
    list2.add("8");
    
    redisTemplate.opsForHash().put("test", "map1", list.toString()); // [1, 2, 3, 4]
    redisTemplate.opsForHash().put("test", "map2", list2.toString()); // [5, 6, 7, 8]
    
    List<String> keys = new ArrayList<>();
    keys.add("map1");
    keys.add("map2");
    
    System.out.println(redisTemplate.opsForHash().multiGet("test", keys)); // [[1, 2, 3, 4], [5, 6, 7, 8]]
    System.out.println(redisTemplate.opsForHash().multiGet("test", keys) instanceof List); // true

    13) scan

    获取所以匹配条件的Hash键中key的值。我查过一些资料,大部分写的是无法模糊匹配,我自己尝试了一下,其实是可以的。如下,使用scan模糊匹配hash键的key中,带SCAN的key。
    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    List<String> list2 = new ArrayList<>();
    list2.add("5");
    list2.add("6");
    list2.add("7");
    list2.add("8");
    List<String> list3 = new ArrayList<>();
    list3.add("9");
    list3.add("10");
    list3.add("11");
    list3.add("12");
    Map<String, String> valueMap = new HashMap<>();
    valueMap.put("map1", list.toString());
    valueMap.put("SCAN_map2", list2.toString());
    valueMap.put("map3", list3.toString());
    
    redisTemplate.opsForHash().putAll("test", valueMap); // {SCAN_map2=[5, 6, 7, 8], map3=[9, 10, 11, 12], map1=[1, 2, 3, 4]}
    
    Cursor<Map.Entry<String, String>> cursor = redisTemplate.opsForHash().scan("test", ScanOptions.scanOptions().match("*SCAN*").build());
    if (cursor.hasNext()) {
        while (cursor.hasNext()) {
            Map.Entry<String, String> entry = cursor.next();
            System.out.println(entry.getValue()); // [5, 6, 7, 8]
        }
    }

    引入pom依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        <version>2.0.5.RELEASE</version>
    </dependency>

    新建配置文件

    然后需要新建一个RedisConfig配置文件。

    package com.detectivehlh;
    
    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    
    /**
     * RedisConfig
     *
     * @author Lunhao Hu
     * @date 2019-01-17 15:12
     **/
    @Configuration
    public class RedisConfig {
        @Bean
        public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            //redis序列化
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            jackson2JsonRedisSerializer.setObjectMapper(om);
    
            StringRedisTemplate template = new StringRedisTemplate(factory);
            template.setValueSerializer(jackson2JsonRedisSerializer);
            template.setHashKeySerializer(jackson2JsonRedisSerializer);
            template.setHashValueSerializer(jackson2JsonRedisSerializer);
            template.setValueSerializer(jackson2JsonRedisSerializer);
            template.afterPropertiesSet();
            return template;
        }
    }

    将redisTemplate注入到需要使用的地方。

    @Autowired
    private RedisTemplate redisTemplate;
  • 相关阅读:
    动手动脑2
    假期第五周学习记录
    假期第四周学习记录
    假期第三周学习记录
    假期第二周学习记录
    执行$JAVA_HOME/bin/java -version和java -version命令输出结果不一致
    假期第一周学习记录
    使用VMware创建虚拟机并下载linux系统镜像文件
    VMware Worstation下载安装
    第十七周学习进度
  • 原文地址:https://www.cnblogs.com/xzjf/p/11124766.html
Copyright © 2011-2022 走看看