在Redis里面,为了确保数据的安全性以及放便快速存储,任何类型的数据,在Redis内部都是采用二进制的方式存储的,这就导致,当我们存入一个字符串时,可能最终取出的结果会乱掉:
我们在存取的时候,这样的效果显然是不想看到的,如何解决?
SpringBoot给我们提供了两种方式:
可以看到StringRedisTemplate继承RedisTemplate
其实他们的区别在于使用的序列化方式不一样,StringRedisTemplate使用的是序列化为String的序列化方式,RedisTemplate使用的是JDK的序列化方式,使用起来不太友好
StringRedisTemplate:序列化为String的方式
RedisTemplate:序列化方式是JDK的序列化方式
方法 | 返回值 | 对应操作 |
---|---|---|
opsForValue() | ValueOperations | 操作String |
opsForHash() | HashOperations | 操作hash |
opsForSet() | SetOperations | 操作set |
opsForList() | ListOperations | 操作list |
opsForZSet() | ZSetOperations | 操作有序set |
除此之外,还有一些与Key相关的操作,可直接通过RedisTemplate对象去调用。
Redis命令 | StringRedisTemplate/RedisTemplate | 说明 |
---|---|---|
KEYS* KEYS 星key星 KEYS 星key KEYS key星 | redisTemplate.keys(key); | 获取所有key,模糊查询key(支持通配符*) |
EXPIRE key 10 | redisTemplate.expire(key,time,TimeUnit.SECONDS); | 指定key缓存失效时间 |
EXPIREAT key 1293840000 | redisTemplate.expireAt(key, date); | 指定key缓存到期时间 |
TTL key | redisTemplate.getExpire(key, TimeUnit.SECONDS); | 根据key获取过期时间 |
EXISTS key | redisTemplate.hasKey(key); | 判断key是否存在 |
EXISTS key1 key2 key3 | redisTemplate.countExistingKeys(Arrays.asList(key)); | 检查key存在的数量 |
DEL key | redisTemplate.delete(key); | 删除指定key缓存 |
DEL key1 key2 key3 | redisTemplate.delete(Arrays.asList(keys)); | 批量删除key |
redisTemplate.opsForValue(); // 操作字符串
Redis命令 | StringRedisTemplate/RedisTemplate | 说明 |
---|---|---|
SET key value | set(key,value) | 设置普通缓存 |
SET key value time | set(key,value,time) | 设置缓存过期时间 |
GET key | get(key) | 获取普通缓存 |
INCE key | increment(key, delta) | 递增,可设置增量 |
DECR key | increment(key, -delta) | 递减 |
SETNX key value | setIfAbsent(key,value) | 将 key 的值设为 value ,当且仅当 key 不存在 |
SETEX key value | setIfPresent(key,value) | 判断当前的键的值是否为v,是的话不作操作,不是的话进行替换。如果没有这个键也不会做任何操作 |
GETSET key value | getAndSet(key, value) | key存在设置新值,并返回旧值 |
redisTemplate.opsForHash(); //操作hash类型
更多操作Redis命令 | StringRedisTemplate/RedisTemplate | 说明 |
---|---|---|
HMSET key key1 value1 key2 value2 | putAll(key, map) | 设置缓存 |
HSET key item value | put(key, item, value) | 向一张hash表中放入数据,如果不存在将创建 |
HGET key item | get(key, item) | 获取缓存,字段值 |
HMGET key | entries(key) | 获取hashKey对应的所有键值 |
HVALS | values(key) | 获取hashKey对应的所有键值 |
HEXISTS key item | hasKey(key, item) | 判断hash表中是否有该项的值 |
HINCRBY key item by | increment(key, item, by) | hash递增 如果不存在,就会创建一个 并把新增后的 |
HLEN | lengthOfValue(key,hashkey) | 获取指定hash键指定键值的长度 |
redisTemplate.opsForList(); //操作List类型
操作Redis命令 | StringRedisTemplate/RedisTemplate | 说明 |
---|---|---|
RPUSH key value | rightPush(key, value) | 将list放入缓存,从右边添加 |
LPUSH key value | leftPush(key, value) | 将list放入缓存,从左边添加 |
LRANGE key 0 -1 | range(key, start, end) | 获取list缓存指定范围的内容 |
LLEN key | size(key) | 获取list缓存的长度 |
LINDEX key index | index(key, index) | 通过索引 获取list中的值 |
LSET key index value | set(key, index, value) | 根据索引修改list中的某条数据 |
LREM key count value | remove(key, count, value) | 移除N个值为value |
leftPop(key) | 该函数用于移除上面我们抽象的容器中的最左边的一个元素。 | |
rightPop(key) | 该函数用于移除上面我们抽象的容器中的最右边的一个元素。 |
redisTemplate.opsForSet(); //操作Set类型
操作Redis命令 | StringRedisTemplate/RedisTemplate | 说明 |
---|---|---|
SMEMBEredisTemplate key | memberedisTemplate(key) | 根据key获取Set中的所有值 |
SISMEMBER key value | isMember(key, value) | 根据value从一个set中查询,是否存在 |
SADD key value1 value2 | add(key, values) | 将数据放入set缓存 |
SCARD key | size(key) | 获取set缓存的长度 |
SREM key value1 value2 | remove(key, values) | 移除值为value的 |
SDIFF key1, key2 | difference(key1, key2) | 求两个key对应的set的差集(不包括右边的) |
SINTER key1, key2 | intersect(key1, key2) | 求两个key对应的set的交集 |
SUNION key1, key2 | set.union(key1, key2) | 求两个key对应的set的并集 |
redisTemplate.opsForZSet(); //操作ZSet(有序集合)类型
- package com.kang.redis.controller;
-
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.SetOperations;
- import org.springframework.data.redis.core.StringRedisTemplate;
- import org.springframework.data.redis.core.ValueOperations;
- import org.springframework.data.redis.core.ZSetOperations;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import java.util.List;
- import java.util.Map;
- import java.util.concurrent.TimeUnit;
-
- /**
- * @Author Emperor Kang
- * @ClassName RedisController
- * @Description TODO
- * @Date 2022/8/11 14:36
- * @Version 1.0
- * @Motto 让营地比你来时更干净
- */
- @RestController
- @Slf4j
- public class RedisController {
- public static final String key1 = "student#03";
- public static final String key2 = "student#04";
- public static final String key = "student#05";
-
- @Autowired
- private StringRedisTemplate redisTemplate;
-
- @GetMapping("/string")
- public void redisForString() throws InterruptedException {
- test1();
- test2();
- test3();
- test4();
- }
-
- @GetMapping("/hashmap")
- public void redisForHashMap() throws InterruptedException {
- test5();
- test6();
- test7();
- }
-
- @GetMapping("/list")
- public void redisForList() throws InterruptedException {
- test8();
- }
-
- @GetMapping("/set")
- public void redisForSet() throws InterruptedException {
- test9();
- }
-
- @GetMapping("/ZSet")
- public void redisForZSet() throws InterruptedException {
- test10();
- }
-
- /**
- * 操作ZSet
- */
- private void test10() {
- //添加周星星同学成绩
- redisTemplate.opsForZSet().add(key,"语文",98);
- redisTemplate.opsForZSet().add(key,"数学",87);
- redisTemplate.opsForZSet().add(key,"英语",75);
- //获取分数最高的成绩
- ZSetOperations.TypedTuple
values = redisTemplate.opsForZSet().popMax(key); - //打印值
- log.info("周星星最好成绩科目是:"+values.getValue());
- log.info("周星星最好成绩:"+values.getScore());
- log.info("======================================================================");
- }
-
- /**
- * 操作set
- */
- private void test9() {
- SetOperations
set = redisTemplate.opsForSet(); - set.add(key1,"a");
- set.add(key1,"b");
- set.add(key1,"c");
-
- set.add(key2,"b");
- set.add(key2,"c");
- set.add(key2,"d");
-
- System.out.println("key1 = " + set.members(key1));
- System.out.println("key2 = " + set.members(key2));
-
- log.info("set.difference(key1,key2) = " + set.difference(key1, key2));
- log.info("set.intersect(key1,key2) = " + set.intersect(key1, key2));
- log.info("set.union(key1,key2) = " + set.union(key1, key2));
- log.info("======================================================================");
- }
-
- /**
- * 操作list
- */
- private void test8() {
- redisTemplate.opsForList().leftPush(key,"周星星");
- redisTemplate.opsForList().leftPush(key, "张敏");
- redisTemplate.opsForList().leftPush(key, "李大锤");
- String value = redisTemplate.opsForList().rightPop(key);
- String value2 = redisTemplate.opsForList().leftPop(key);
- log.info("从list的右边获取数据:{}",value);
- log.info("从list的左边获取数据:{}",value2);
- log.info("当前list的长度为:{}",redisTemplate.opsForList().size(key));
- log.info("======================================================================");
- }
-
- /**
- * 获取长度
- */
- private void test7() {
- Long length = redisTemplate.opsForHash().lengthOfValue(key, "id");
- log.info("获取map中指定值的长度:{}",length);
- log.info("======================================================================");
- }
-
- /**
- * 获取所有的值
- */
- private void test6() {
- List
- log.info("获取map中所有的值:{}",values);
- log.info("======================================================================");
- }
-
- /**
- * 操作hashmap
- */
- private void test5() {
- redisTemplate.opsForHash().put(key,"id","001");
- redisTemplate.opsForHash().put(key,"name","张三");
- redisTemplate.opsForHash().put(key,"age","18");
- redisTemplate.opsForHash().put(key,"sex","男");
- Map
- log.info("获取所有的键值对:{}",entries);
- log.info("======================================================================");
- }
-
- /**
- * 不带过期时间
- */
- private void test1() {
- redisTemplate.opsForValue().set("name","看看有什么不好呢");
- String name = redisTemplate.opsForValue().get("name");
- log.info("name:{}",name);
- log.info("======================================================================");
- }
-
- /**
- * 带过期时间
- * @throws InterruptedException
- */
- private void test2() throws InterruptedException {
- redisTemplate.opsForValue().set("name","我不看",5, TimeUnit.SECONDS);
- String name = redisTemplate.opsForValue().get("name");
- log.info("第1次获取name:{}",name);
-
- Thread.sleep(6000);
-
- String name2 = redisTemplate.opsForValue().get("name");
- log.info("第2次获取name:{}",name2);
- log.info("======================================================================");
- }
-
- /**
- * ValueOperations
- */
- private void test3() {
- ValueOperations
value = redisTemplate.opsForValue(); - log.info("ValueOperations
.get()={}" ,value.get("p1")); - log.info("======================================================================");
- }
-
- /**
- * 将 key 的值设为 value ,当且仅当 key 不存在
- */
- private void test4() {
- Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("name", "看看有什么不好呢");
- Boolean aBoolean1 = redisTemplate.opsForValue().setIfAbsent("name", "我不看");
- System.out.println("aBoolean = " + aBoolean);
- System.out.println("aBoolean1 = " + aBoolean1);
- log.info("======================================================================");
- }
- }
- package com.kang.redis.config;
-
- 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.serializer.RedisSerializer;
-
- /**
- * @Author Emperor Kang
- * @ClassName RedisConfig
- * @Description redis配置类
- * @Date 2022/8/11 11:17
- * @Version 1.0
- * @Motto 让营地比你来时更干净
- */
- @Configuration
- public class RedisConfig {
- @Bean
- public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
- RedisTemplate
- redisTemplate.setConnectionFactory(redisConnectionFactory);
- redisTemplate.setKeySerializer(RedisSerializer.string());
- redisTemplate.setValueSerializer(RedisSerializer.string());
-
- redisTemplate.setHashKeySerializer(RedisSerializer.string());
- redisTemplate.setHashValueSerializer(RedisSerializer.string());
-
- redisTemplate.afterPropertiesSet();
- return redisTemplate;
- }
- }