Redis 数据结构


结构类型

结构存储的值

结构的读写能力

String

可以是字符串、整数或者浮点数

对整个字符串或者字符串的其中一部分执行操作;对象和浮点数执行自增(increment)或者自减(decrement)

List

一个链表,链表上的每个节点都包含了一个字符串

从链表的两端推入或者弹出元素;根据偏移量对链表进行修剪(trim);读取单个或者多个元素;根据值来查找或者移除元素

Set

包含字符串的无序收集器(unorderedcollection),并且被包含的每个字符串都是独一无二的、各不相同

添加、获取、移除单个元素;检查一个元素是否存在于某个集合中;计算交集、并集、差集;从集合里卖弄随机获取元素

Hash

包含键值对的无序散列表

添加、获取、移除单个键值对;获取所有键值对

Zset

字符串成员(member)与浮点数分值(score)之间的有序映射,元素的排列顺序由分值的大小决定

添加、获取、删除单个元素;根据分值范围(range)或者成员来获取元素


RedisTemplate应用

Spring封装了RedisTemplate对象来进行对Redis的各种操作

public class RedisTemplate<K,V> extends RedisAccessor implements RedisOperations<K,V>, BeanClassLoaderAware

RedisTemplate常用方法

 1)Boolean delete(K key) 

2)Long delete(Collection<K> keys)

3)Boolean hasKey(K key)

4)Boolean expire(K key,long timeout,TimeUnit unit)

timeout:过期时间

unit:时间单位

    5)Boolean expireAt(K key,Date date)    ----设置到date时间点过期

6)Long getExpire(K key)    ----获取过期时间

    7)Set<K> keys(K pattern)    ----获取符合条件的所有key

pattern:通配条件 (* 号是通配符)

eg:keys("*") ——查询所有的key值

      keys("a*") ——查询以a开头的所有key

8)void rename(K oldKey, K newKey)    ----key值重命名

 ----操作字符串,如下

----操作list,如下

----操作set,如下

----操作zset,如下

 *) boundValueOps(K key),boundListOps(K key)……

RedisTemplate中定义了对5种数据结构操作

redisTemplate.opsForValue();//操作字符串 redisTemplate.opsForHash();//操作hash redisTemplate.opsForList();//操作list redisTemplate.opsForSet();//操作set redisTemplate.opsForZSet();//操作有序set


RedisTemplate对五种数据类型操控

一、Redis的String数据结构 (推荐使用StringRedisTemplate)

注意:如果使用RedisTemplate需要更改序列化方式

public interface ValueOperations<K,V>    -->ValueOperations可以对String数据结构进行操作

1、插入数据  

1)void set( K  key, V  value) 

key:储存键; value:储存值

使用:redisTemplate.opsForValue().set("name","tom");

结果:redisTemplate.opsForValue().get("name")

输出结果为tom

 2)void set(K key, V value, long timeout, TimeUnit unit)

timeout:过期时间; unit:时间单位

使用:redisTemplate.opsForValue().set("name","tom",10, TimeUnit.SECONDS);

结果:redisTemplate.opsForValue().get("name")由于设置的是10秒失效,十秒之内查询有结果,十秒之后返回为null


3)void set(K key, V value, long offset) ----该方法是用 value 参数覆写(overwrite)给定 key 所储存的字符串值,从偏移量 offset 开始



offset:value值覆写偏移量

使用:template.opsForValue().set("key","hello world"); template.opsForValue().set("key","redis", 6);

System.out.println("***************"+template.opsForValue().get("key"));

结果:***************hello redis

4)Boolean setIfAbsent(K key, V value) ----该方法不会覆盖已存在数据


使用:System.out.println(template.opsForValue().setIfAbsent("multi1","multi1"));//false multi1之前已经存在 System.out.println(template.opsForValue().setIfAbsent("multi111","multi111"));//true multi111之前不存在 结果: false

true

    5)void multiSet(Map<? extends K, ? extends V> m) ----为多个键分别设置它们的值


使用:Map<String,String> maps = new HashMap<String, String>();
          maps.put("multi1","multi1");
          maps.put("multi2","multi2");
          maps.put("multi3","multi3");
          template.opsForValue().multiSet(maps);
          List<String> keys = new ArrayList<String>();
          keys.add("multi1");
          keys.add("multi2");
          keys.add("multi3");
          System.out.println(template.opsForValue().multiGet(keys));
结果:[multi1, multi2, multi3]

  6)Boolean multiSetIfAbsent(Map<? extends K, ? extends V> m)   ----为多个键分别设置它们的值,如果存在则返回false,不存在返回true


使用:Map<String,String> maps = new HashMap<String, String>();
          maps.put("multi11","multi11");
          maps.put("multi22","multi22");
          maps.put("multi33","multi33");
          Map<String,String> maps2 = new HashMap<String, String>();
          maps2.put("multi1","multi1");
          maps2.put("multi2","multi2");
          maps2.put("multi3","multi3");
          System.out.println(template.opsForValue().multiSetIfAbsent(maps));
          System.out.println(template.opsForValue().multiSetIfAbsent(maps2));
结果:true
          false

    7)Long increment(K key, long delta)


使用:template.opsForValue().increment("increlong",1);

System.out.println("***************"+template.opsForValue().get("increlong"));

结果:***************1

8)Double increment(K key, double delta) 


使用:template.opsForValue().increment("increlong",1.2);

System.out.println("***************"+template.opsForValue().get("increlong"));

结果:***************2.2

9)Integer append(K key, String value) 


使用:template.opsForValue().append("appendTest","Hello");

System.out.println(template.opsForValue().get("appendTest"));

template.opsForValue().append("appendTest","world");

System.out.println(template.opsForValue().get("appendTest"));

结果:Hello Helloworld


2、查询数据

 1)V get(Object key)


使用:template.opsForValue().set("key","hello world");

System.out.println("***************"+template.opsForValue().get("key"));

结果:***************hello world

2)V getAndSet(K key, V value)

value:新的值

使用:template.opsForValue().set("getSetTest","test");

System.out.println(template.opsForValue().getAndSet("getSetTest","test2"));

结果:test

3)List<V> multiGet(Collection<K> keys)


使用:Map<String,String> maps = new HashMap<String, String>();
          maps.put("multi1","multi1");
          maps.put("multi2","multi2");
          maps.put("multi3","multi3");
          template.opsForValue().multiSet(maps);
          List<String> keys = new ArrayList<String>();
          keys.add("multi1");
          keys.add("multi2");
          keys.add("multi3");
          System.out.println(template.opsForValue().multiGet(keys));
结果:[multi1, multi2, multi3]

4)String get(K key, long start, long end)


使用:appendTest对应的value为Helloworld
        System.out.println("*********"+template.opsForValue().get("appendTest",0,5));
结果:*********Hellow
使用:System.out.println("*********"+template.opsForValue().get("appendTest",0,-1));
结果:*********Helloworld
使用:System.out.println("*********"+template.opsForValue().get("appendTest",-3,-1));
结果:*********rld

5)Long size(K key)


使用:template.opsForValue().set("key","hello world");

System.out.println("***************"+template.opsForValue().size("key"));

结果:***************11

6) Boolean setBit(K key, long offset, boolean value) 

使用:template.opsForValue().set("bitTest","a");
          // 'a' 的ASCII码是 97。转换为二进制是:01100001
          // 'b' 的ASCII码是 98 转换为二进制是:01100010
          // 'c' 的ASCII码是 99 转换为二进制是:01100011
          //因为二进制只有0和1,在setbit中true为1,false为0,因此我要变为'b'的话第六位设置为1,第七位设置为0
          template.opsForValue().setBit("bitTest",6, true);
          template.opsForValue().setBit("bitTest",7, false);
          System.out.println(template.opsForValue().get("bitTest"));
结果:b

7)Boolean getBit(K key, long offset) 


使用:System.out.println(template.opsForValue().getBit("bitTest",7));

结果:false

二、Redis的List数据结构 

更改RedisTemp序列化方式

Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setKeySerializer(jackson2JsonRedisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashKeySerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);

public interface ListOperations<K,V>
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)
ListOperations专门操作list列表:

1、插入数据

1) leftPush(K key, V value) 


使用:template.opsForList().leftPush("list","java");
        template.opsForList().leftPush("list","python");
        template.opsForList().leftPush("list","c++");
结果:返回的结果为推送操作后的列表的长度
2

2)Long leftPushAll(K key, V... values)


使用:String[] stringarrays = new String[]{"1","2","3"};

template.opsForList().leftPushAll("listarray",stringarrays);

System.out.println(template.opsForList().range("listarray",0,-1));

结果:[3, 2, 1]

3)Long leftPushAll(K key, Collection<V> values)

使用:List<Object> strings = new ArrayList<Object>();
        strings.add("1");
        strings.add("2");
        strings.add("3");
       template.opsForList().leftPushAll("listcollection4", strings);
       System.out.println(template.opsForList().range("listcollection4",0,-1));
结果:[3, 2, 1]

4)Long leftPushIfPresent(K key, V value) 


使用:System.out.println(template.opsForList().leftPushIfPresent("leftPushIfPresent","aa"));
        System.out.println(template.opsForList().leftPushIfPresent("leftPushIfPresent","bb"));
       ==========分割线===========
       System.out.println(template.opsForList().leftPush("leftPushIfPresent","aa"));
       System.out.println(template.opsForList().leftPushIfPresent("leftPushIfPresent","bb"));
结果:
0
==========分割线===========
2

 5)Long leftPush(K key, V pivot, V value)


使用:template.opsForList().leftPush("list","java","oc");

System.out.print(template.opsForList().range("list",0,-1));

结果:[c++, python, oc, java, c#, c#]

6)Long rightPush(K key, V value) / rightPushAll(K key, V... values)

7)void set(K key, long index, V value) 

使用:System.out.println(template.opsForList().range("listRight",0,-1));

template.opsForList().set("listRight",1,"setValue");

System.out.println(template.opsForList().range("listRight",0,-1));

结果:[java, python, oc, c++] [java, setValue, oc, c++]

 2、获取数据

1)List<V> range(K key, long start, long end)


使用:System.out.println(template.opsForList().range("list",0,-1));

结果:[c#, c++, python, java, c#, c#]

2)Long size(K key)

使用:System.out.println(template.opsForList().size("list"));

结果:6


3)V index(K key, long index)


使用:System.out.println(template.opsForList().range("listRight",0,-1));

System.out.println(template.opsForList().index("listRight",2));

结果:[java, oc, c++] c++

4)V leftPop(K key)/rightPop(K key)


使用:System.out.println(template.opsForList().range("list",0,-1));
          System.out.println(template.opsForList().leftPop("list"));
          System.out.println(template.opsForList().range("list",0,-1));
结果:
          [c++, python, oc, java, c#, c#]
          c++
          [python, oc, java, c#, c#]

5)V leftPop(K key, long timeout, TimeUnit unit) /rightPop(K key, long timeout, TimeUnit unit)

用法同上

6)V rightPopAndLeftPush(K sourceKey, K destinationKey) 


使用:System.out.println(template.opsForList().range("list",0,-1));
          template.opsForList().rightPopAndLeftPush("list","rightPopAndLeftPush");
          System.out.println(template.opsForList().range("list",0,-1));
          System.out.println(template.opsForList().range("rightPopAndLeftPush",0,-1));
结果:[oc, java,c#]
          [oc, java]
          [c#]

3、其他操作

1)void trim(K key, long start, long end) 


使用:System.out.println(template.opsForList().range("list",0,-1));

//裁剪第一个元素

结果:[c#, c++, python, java, c#, c#]

[c++, python, java, c#, c#]

2)Long remove(K key, long count, Object value) 

计数参数以下列方式影响操作:
count> 0:删除等于从头到尾移动的值的元素。
count <0:删除等于从尾到头移动的值的元素。
count = 0:删除等于value的所有元素。


使用:System.out.println(template.opsForList().range("listRight",0,-1));

//将删除列表中存储的列表中第一次次出现的“setValue”。

结果:[java, setValue, oc, c++] [java, oc, c++]

三、Redis的Hash数据机构

    Redis的散列可以让用户将多个键值对存储到一个Redis键里面。
    public interface HashOperations<H,HK,HV>
    HashOperations提供一系列方法操作hash:

常用方法如下

 1)Long delete(H key, Object... hashKeys)

 2)Boolean hasKey(H key, Object hashKey) 

3)HV get(H key, Object hashKey)

4)List<HV> multiGet(H key, Collection<HK> hashKeys)

5)Long increment(H key, HK hashKey, long delta) 

6)Double increment(H key, HK hashKey, double delta) 

7)Set<HK> keys(H key) 

  8)Long size(H key) 

9)void putAll(H key, Map<? extends HK, ? extends HV> m) 

10)void put(H key, HK hashKey, HV value)

11)Boolean putIfAbsent(H key, HK hashKey, HV value) 

12)List<HV> values(H key)

13)Map<HK, HV> entries(H key) 

 14)Cursor<Map.Entry<HK, HV>> scan(H key, ScanOptions options) 


四、Redis的Set数据结构

 Redis的Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
    Redis 中 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
    public interface SetOperations<K,V>
    SetOperations提供了对无序集合的一系列操作:

常用方法如下:

1)Long add(K key, V... values)

2)Long remove(K key, Object... values) 

3)V pop(K key) 

4)Boolean move(K key, V value, K destKey)

5)Long size(K key)

6)Boolean isMember(K key, Object o) 

7)Set<V> intersect(K key, K otherKey) 

8)Set<V> intersect(K key, Collection<K> otherKeys) 

9)Long intersectAndStore(K key, K otherKey, K destKey) 

10)Long intersectAndStore(K key, Collection<K> otherKeys, K destKey) 

11)Set<V> union(K key, K otherKey)

 12)Set<V> union(K key, Collection<K> otherKeys) 

  13)Long unionAndStore(K key, K otherKey, K destKey) 

 14)Long unionAndStore(K key, Collection<K> otherKeys, K destKey)

15)Set<V> difference(K key, K otherKey) 

16)Set<V> difference(K key, Collection<K> otherKeys)

17)Long differenceAndStore(K key, K otherKey, K destKey) 

18)Long differenceAndStore(K key, Collection<K> otherKeys, K destKey) 

19)Set<V> members(K key) 

 20)V randomMember(K key) 

 21)Set<V> distinctRandomMembers(K key, long count) 

22)List<V> randomMembers(K key, long count) 

23)Cursor<V> scan(K key, ScanOptions options)

五、Redis的ZSet数据结构

   Redis有序集合和无序集合一样也是string类型元素的集合,且不允许重复的成员。
    不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
    有序集合的成员是唯一的,但分数(score)却可以重复。
    public interface ZSetOperations<K,V>
    ZSetOperations提供了一系列方法对有序集合进行操作:

常用方法如下:

 1)Boolean add(K key, V value, double score) 

2)Long add(K key, Set<TypedTuple<V>> tuples) 

  3)Long remove(K key, Object... values)

 4)Double incrementScore(K key, V value, double delta) 

  5)Long rank(K key, Object o) 

6)Long reverseRank(K key, Object o) 

  7)Set<V> range(K key, long start, long end)

8)Set<TypedTuple<V>> rangeWithScores(K key, long start, long end)

9)Set<V> rangeByScore(K key, double min, double max)

10)Set<TypedTuple<V>> rangeByScoreWithScores(K key, double min, double max) 

11)Set<V> rangeByScore(K key, double min, double max, long offset, long count) 

12)Set<TypedTuple<V>> rangeByScoreWithScores(K key, double min, double max, long offset, long count) 

13)Set<V> reverseRange(K key, long start, long end)

14)Set<TypedTuple<V>> reverseRangeWithScores(K key, long start, long end) 

  15)Long count(K key, double min, double max) 

16)Long size(K key) 

17)Long zCard(K key) 

18)Double score(K key, Object o) 

 19)Long removeRange(K key, long start, long end)

20)Long removeRangeByScore(K key, double min, double max) 

 21)Long unionAndStore(K key, K otherKey, K destKey) 

22)Long unionAndStore(K key, Collection<K> otherKeys, K destKey) 

  23)Long intersectAndStore(K key, K otherKey, K destKey) 

24)Long intersectAndStore(K key, Collection<K> otherKeys, K destKey)

25)Cursor<TypedTuple<V>> scan(K key, ScanOptions options)