## Redis由入门到精通 引言 Redis是一种基于键值对(key-value)的高性能的NoSql数据库,它提供了各种数据结构存储,具有高性能的读写功能,是目前企业中应用极其广泛的一种数据库。 官网:https://redis.io ### 1. NoSql数据库简介 #### 1.1 技术发展 web1.0时代,数据访问量很有限,用高性能的单点服务器可以解决大部分问题。随着web2.0时代的到来后,用户访问量大幅度的提升,同时产生了大量的用户数据,加上后来的智能移动设备的普及,所有的互联网平台都面临了巨大的性能挑战,其实主要的挑战来自于服务器的CPU及内存压力以及MySql的读写IO压力 。 #### 1.2 NoSql数据库 ##### 1.2.1 NoSql的概念 NoSql不要理解成“不是SQL”,是指“Not Only Sql”,意为不仅仅是Sql,它里面既有SQL,还有SQL不能解决的问题,泛指非关系型数据库。NoSql不依赖业务逻辑的方式存储,而以简单的Key-Value模式存储,因此大大的增加了数据库的扩展能力。 - 不遵守SQL标准 - 不支持ACID - 远超于SQL的性能 ##### 1.2.2 适用场景 - 对数据高并发的读写 - 海量数据的读写 Nosql吞吐量 ##### 1.2.3 常见的NoSql数据库 - Memcache - 是一款很早就出现的数据库 - 数据都在内存中,一般 不支持持久化 - 支持简单的key-value模式,支持类型单一。 - 一般是作为缓存数据库辅助持久化的数据库。 - Redis - 几乎覆盖了Memcache的绝大部分功能 - 数据都在内存中,支持持久化,主要用作备份恢复。 - 除了支持简单的key-value模式,还支持多种数据结构的存储,比如list、set、hash、zset等 - 也是作为缓存数据库辅助持久化的数据库。 - MongoDB - 高性能,开源、模式自由的文档型数据库 - 数据都在内存中,如果内存不足,把不常用的数据保存在硬盘中 - 虽然是key-value模式,但是对value,尤其是json提供了丰富的查询功能 - 支持二进制及大型对象 ##### 1.2.4 数据库排名 ![数据库](Redis.assets/数据库.jpg) ### 2. Redis概述和安装 #### 2.1 Redis概述 Redis 是完全开源免费的,是一个高性能的key-value数据库。Redis的性能十分优越,可以支持每秒十几万的读/写操作,其性能远超关系型数据库,并且支持集群、分布式、主从同步等配置,还支持一定事务的能力。 #### 2.2 Redis在JavaWeb中的应用 在互联网的应用中,往往存在一些需要高速读/写的场合,比如商品的秒杀,抢红包,淘宝、京东的双十一活动或者春运抢票等。这类场合在一个瞬间成千上万的请求就会达到服务器,如果使用的是关系型数据库, 一个瞬间数据库就需要执行成千上万的SQL ,很容易造成数据库的瓶颈,严重的会导致数据库瘫痪,造成Java Web 系统服务崩溃。 在这样的场合的应对办法往往是考虑异步写入数据库,而在高速读/写的场合中单单使用Redis 去应对, 把这些需要高速读/写的数据, 缓存到Redis 中,而在满足一定的条件下,触发这些缓存的数据写入数据库中。 咱们再进一步深入论述这个过程: 当一个请求达到服务器,只是把业务数据先在Redis 读/写,而没有进行任何对数据库的操作,换句话说系统仅仅是操作Redis 缓存,而没有操作数据库,这个速度就比操作数据库要快得多,从而达到需要高速响应的效果。 但是一般缓存不能持久化,因此需要把这些数据存入数据库,所以在一个请求操作完Redis 的读/写后,会去判断该高速读/写的业务是否结束。这个判断的条件往往就是秒杀商品剩余个数为0 ,抢红包金额为0 ,如果不成立,则不会操作数据库;如果成立,则触发事件将Redis 缓存的数据以批量的形式一次性写入数据库,从而完成持久化的工作。 假设面对的是一个商品秒杀的场景,从上面的流程看, 一个用户抢购商品,绝大部分的场合都是在操作内存数据库Redis , 而不是磁盘mysql数据库,所以其性能更为优越。只有在商品被抢购一空后才会触发系统把Redis 缓存的数据写入数据库磁盘中, 这样系统大部分的操作基于内存,就能够在秒杀的场合高速响应用户的请求,达到快速应答。 #### 2.3 Redis的安装 ##### 2.3.1 Windows安装步骤 1.下载安装包 **下载地址:**https://github.com/dmajkic/redis 2.打开你刚才解压的文件路径 3.双击redis-server.exe启动服务 4.使用redis-cli.exe客户端来连接 5.测试连接 输入ping命令,输出PONG代表连接成功 ##### 2.3.2 Linux安装步骤 卸载步骤: 查看是否已经安装redis,版本 ~~~shell redis-server -v | redis-cli -v ~~~ 如果存在 ~~~shell ps - ef | grep redis ~~~ 关闭服务或者kill进程 ~~~ kill -9 01234 ~~~ 删除安装目录下的文件 ~~~shell rm -rf /usr/local/bin/redis* ~~~ 1.在线安装gcc环境 ~~~bash yum install gcc-c++ ~~~ 安装完毕后,查看版本号 ~~~bash gcc -v ~~~ 2.下载安装包 官网:https://redis.io/ 打开中文官网下载:http://www.redis.cn/ 3.上传到linux服务器/opt文件下 4.解压压缩包 ~~~bash tar -zxvf redis-6.2.5.tar.gz ~~~ 5.进入redis-6.2.5 ~~~bash cd redis-6.2.5 ~~~ 6.执行make命令 ~~~bash make ~~~ 如果出现:致命错误:jemalloc/jemalloc.h:没有那个文件或目录,则执行下面命令,进行残存文件的清理 ~~~bash make distclean ~~~ 后,继续执行 make命令,执行完毕后,可再make一次,然后就执行很快了 7.执行命令 ~~~bash make install ~~~ redis的默认安装路径和java是一样的,也在/usr下面 8.进入usr目录,找到local下面的bin目录,就可以看到redis-server,自此redis安装就完成了 ~~~ cd /usr/local/bin ~~~ ##### 2.3.3 Linux下配置Redis 1.在安装的bin目录下创建文件夹 ~~~bash mkdir redisconfig ~~~ 2.拷贝文件 ~~~bash cp /opt/redis-6.2.5/redis.conf redisconfig ~~~ 以后使用这个redisconfig下面的redis.conf就好了,原来的解压目录下的配置文件不需要管了 3.进行后台启动 因为redis不是默认后台启动的,所以得修改配置文件 ~~~bash vim redis.conf ~~~ 找到daemonize no,把no修改为yes,保存并退出,这样redis就会以后台方式启动 4.启动redis服务 回到 /usr/local/bin目录,运行 ~~~bash cd /usr/local/bin ~~~ ~~~bash redis-server redisconfig/redis.conf ~~~ 意思是通过指定的配置文件redisconfig/redis.conf来启动 5.使用客户端进行连接 ~~~bash redis-cli -p 6379 ~~~ 输入命令 ~~~bash ping ~~~ 显示PONG,就表示连接成功! 6.测试连接 ~~~bash set name mengshujun ~~~ ~~~bash get name ~~~ 可以查看里面还有哪些键 ~~~bash keys * ~~~ 7.查看redis的进程是否开启 在xshell中,复制一个会话,输入 ~~~bash ps -ef | grep redis ~~~ 8.关闭redis服务 在127.0.0.1:6379> 下输入 ~~~bash shutdown exit ~~~ ### 3. Redis配置文件 #### 3.1 远程连接配置 bind 127.0.0.1 -:: 1 表示只能接受本机的访问,要通过其他电脑远程进行连接就应该注释,找到后注释掉,默认没有注释。 protected-mode yes 表示开启保护模式,只能通过本机访问,远程不能访问,改为no就可以进行远程访问了 #### 3.2 配置连接密码 修改redis.conf配置文件 ~~~bash # requirepass foobared requirepass 866qa@WSDE# ~~~ 保存后重启redis就可以了 小技巧: 我们通常在vim下要查找字符串的时候, 都是输入 / 或者 ? 加 需要查找的字符串来进行搜索,比如想搜索 requirepass这个单词, 可以输入 /requirepass或者 ?requirepass, 两者的区别是前者是从上往下搜索,后者是从下往上搜索。按n往下搜索。 #### 3.3 关闭linux防火墙 查看linux的防火墙是否关闭 ~~~bash #查看防火墙的启动状态 systemctl status firewalld # 关闭防火墙 systemctl stop firewalld #开启防火墙 systemctl start firewalld #查看开放的端口号 firewall-cmd --list-all #在防火墙中设置开放的端口号 firewall-cmd --zone=public --add-port=6379/tcp --permanent #开启端口后,需要重启防火墙才生效 systemctl restart firewalld | firewall-cmd --reload # 如果有不用的端口,则进行移除 firewall-cmd --permanent --remove-port=8001/tcp ~~~ #### 3.4 连接redis服务 1.xshell连接 ~~~bash redis-cli -h host -p port -a password #host:远程redis服务器host #port:远程redis服务端口 #password:远程redis服务密码(无密码的的话就不需要-a参数了) ~~~ 示例: ~~~shell redis-cli -h 127.0.0.1 -p 6379 -a 123456 ~~~ 或者,如果有密码,连接的时候也可输入,回车即可。 ~~~shell auth 123456 ~~~ 2.redisdesktop工具连接 安装略 ### 4. 常用五大数据类型 **基础命令学习** 针对key的操作: redis默认有16个数据库,可以打开相关配置文件进行查看,默认使用的是第0个数据库。 select 【num】 切换数据库,num代表0-15的数字 dbsize 可以查看数据库的大小,里面包含的key的个数 flushdb 清空当前库 flushall 清空(通杀)所有的库 exists key 判断某个Key是否存在 del key删除指定的key数据 unlink key 根据value选择非阻塞删除,仅将key从keyspace元数据中删除,真正的删除会在后续慢慢异步操作 type key 查看key对应的value是什么类型 expire key 10 为给定的key设置过期时间10秒钟 ttl key 查看还有多少秒过期 -1表示永不过期 -2表示已经过期 #### 4.1 Redis字符串(String) String是Redis最基本的类型, 一个key对应一个value,一个value的最多是512MB。String类型是二进制的安全的,意味着Redis的String可以包含任何数据。比如jpg图片或者序列化对象。 | 序号 | 命令及描述 | | ---- | :----------------------------------------------------------- | | 1 | SET key value 设置指定 key 的值 | | 2 | GET key 获取指定 key 的值。 | | 3 | GETRANGE key start end 返回 key 中字符串值的子字符 | | 4 | GETSET key value 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 | | 5 | SETNX key value 只有在 key 不存在时设置 key 的值。 **分布式锁** | | 6 | STRLEN key 返回 key 所储存的字符串值的长度。 | | 7 | MSET key value [key value ...\] 同时设置一个或多个 key-value 对。 | | 8 | MGET key1 [key2..\] 获取所有(一个或多个)给定 key 的值。 | | 9 | MSETNX key value [key value ...\] 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。 | | 10 | INCR key 将 key 中储存的数字值增一。 | | 11 | DECR key将 key 中储存的数字值减一。 | | 12 | INCRBY key increment 将 key 所储存的值加上给定的增量值(increment) 。 | | 13 | DECRBY key decrementkey 所储存的值减去给定的减量值(decrement) 。 | | 14 | APPEND key value 如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。 | #### 4.2 Redis列表(List) 特征:有序的,不唯一的 Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边),它的底层实际是一个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能可能会较差。 一个列表最多可以包含4294967295个元素, 超过40亿个元素。 | 序号 | 命令及描述 | | ---- | ------------------------------------------------------------ | | 1 | LPUSH key value1 value2 在列表左边添加将一个或多个值 | | 2 | RPUSH key value1 value2 在列表右边添加添加一个或多个值 | | 3 | LRANGE key 0 -1 获取列表指定范围内的元素 【-1代表右边第一个 0 -1代表获取所有】 | | 4 | LPOP key 移出并获取列表的左边的第一个元素 【值在键在,值亡键亡】 | | 5 | RPOP key 移出列表的最后一个元素,返回值为移出的元素。【值在键在,值亡键亡】 | | 6 | RPOPLPUSH key1 key2 从key1列表右边移出一个值,插到key2列表左边 | | 7 | LINDEX key index 通过索引获取列表中的元素 | | 8 | LLEN key 获取列表长度 | | 9 | LINSERT key BEFORE\|AFTER value new_value 在列表的元素前或者后插入元素 | | 10 | LREM key count value 移除列表元素,从左边开始删除count个元素 | | 11 | LSET key index value 通过索引设置列表元素的值,会覆盖原有的值 | #### 4.3 Redis集合(Set) 特征:无序的,唯一的 Redis set对外提供的功能与list类似,是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择。 Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。它的内部使用hash结构,所有的value都指向同一个内部值,类似于Java中HashSet。 | 序号 | 命令及描述 | | ---- | ------------------------------------------------------------ | | 1 | SADD key member1 member2向集合添加一个或多个成员 | | 2 | SMEMBERS key 返回集合中的所有成员 | | 3 | SISMEMBER key member 判断 member 元素是否是集合 key 的成员 | | 4 | SCARD key 获取集合的成员数 | | 5 | SREM key member1 移除集合中一个或多个成员 | | 6 | SPOP key 移除并返回集合中的一个随机元素 | | 7 | SRANDMEMBER key count 返回集合中一个或多个随机数 | | 8 | SINTER key1 key2 返回第一个集合与第二个集合之间的交集 | | 9 | SUNION key1 key2 返回第一个集合与第二个集合之间的并集 | | 10 | SDIFF key1 key2 返回第一个集合与第二个集合之间的差异 【key1中,不包含key2中】 | #### 4.4 Redis哈希(Hash) Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。 key: 字符串名称 value:放一个对象 | 序号 | 命令及描述 | | ---- | ------------------------------------------------------------ | | 1 | HSET key field value 将哈希表 key 中的字段 field 的值设为 value 例如:hset users name zhangsan | | 2 | HGET key field 获取存储在哈希表中指定字段的值。例如: hget users name | | 3 | HMSET key field1 value1 field2 value2 同时将多个 field-value (域-值)对设置到哈希表 key 中。 | | 4 | HEXISTS key field 查看哈希表 key 中,指定的字段是否存在。 | | 5 | HKEYS key 获取所有哈希表中的字段(键)。 | | 6 | HVALS key 获取哈希表中所有值。 | | 7 | HINCRBY key field increment 为哈希表 key 中的指定字段的整数值加上增量 increment 。 | | 8 | HSETNX key field value 只有在字段 field 不存在时,设置哈希表字段的值。 | #### 4.5 Redis有序集合(Zset) Redis 有序集合和集合一样也是 string 类型0元素的集合,且不允许重复的成员。 特征:有序的,唯一的 不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。 有序集合的成员是唯一的,但分数(score)却可以重复。 | 序号 | 命令及描述 | | ---- | ------------------------------------------------------------ | | 1 | ZADD key score1 member1 score2 member2向有序集合添加一个或多个成员,或者更新已存在成员的分数 例如:zadd topn 100 java 200 mysql 300 linux 400 c 500 redis | | 2 | ZRANGE key start stop 通过索引区间返回有序集合指定区间内的成员 例如:zrange topn 0 -1 withscores | | 3 | ZRANGEBYSCORE key min max [WITHSCORES\] LIMIT通过分数返回有序集合指定区间内的成员 | | 4 | ZREVRANGEBYSCORE key max min 返回有序集中指定分数区间内的成员,分数从高到低排序 | | 5 | ZINCRBY key increment member 有序集合中对指定成员的分数加上增量 increment | | 6 | ZREM key member 移除有序集合中的一个或多个成员 | | 7 | ZCOUNT key min max 计算在有序集合中指定区间分数的成员数 | | 8 | ZRANK key member 返回有序集合中指定成员的索引 | ### 5. SpringBoot整合Redis Spring Boot整合Redis提供了 RedisTemplate与StringRedisTemplate两个类,其中StringRedisTemplate是RedisTemplate的子类,两个方法基本一致,不同之处主要体现在操作的数据类型不同,RedisTemplate中两个泛型都是Object,意味着存储的key和value都可以是一个对象,而StringRedisTemplate的两个泛型都是String,意味着StringRedisTemplate的key和value都只能是字符串。 StringRedisTemplate<String,String> RedisTemplate<Object,Object> #### 5.1 引入redis依赖 ~~~xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ~~~ #### 5.2 配置设置 ~~~yaml spring: redis: host: 192.168.2.167 port: 6379 password: 123456 database: 0 ~~~ #### 5.3 StringRedisTemplate应用 StringRedisTemplate主要应用于键和值都是String的情况 创建测试类测试: ~~~java package com.example.springredis; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.StringRedisTemplate; @SpringBootTest class SpringRedisApplicationTests { @Autowired private StringRedisTemplate stringRedisTemplate; @Test public void test1(){ Set<String> keys = stringRedisTemplate.keys("*"); keys.forEach(System.out::println); } } ~~~ ##### 5.3.1 操作Keys 直接使用stringRedisTemplate,点方法就可以 ~~~java stringRedisTemplate.type("name"); //获取类型 stringRedisTemplate.delete("name"); //删除指定key stringRedisTemplate.hasKey("name");//判断key是否存在 stringRedisTemplate.getExpire("name");//查看过期时间 -1 代表永不超时 -2 代表过期 ~~~ ##### 5.3.2 操作String 使用stringRedisTemplate.opsForValue()操作的就是字符串类型 ~~~java stringRedisTemplate.opsForValue().set("gender","女"); String gender = stringRedisTemplate.opsForValue().get("gender"); System.out.println(gender); //设置一个key超时时间 stringRedisTemplate.opsForValue().set("code","000098",120, TimeUnit.SECONDS); ~~~ ##### 5.3.3 操作List 使用stringRedisTemplate.opsForList()操作的就是list类型 ~~~java stringRedisTemplate.opsForList().leftPush("names","张三"); stringRedisTemplate.opsForList().leftPushAll("names","张三","李四","王五"); List<String> list=new ArrayList<>(); list.add(0,"老大"); list.add(1,"老二"); list.add(2,"老三"); stringRedisTemplate.opsForList().leftPushAll("names",list); List<String> names = stringRedisTemplate.opsForList().range("names", 0, -1); names.forEach(System.out::println); ~~~ ##### 5.3.4 操作Set 使用stringRedisTemplate.opsForSet()操作的就是set类型 ~~~java stringRedisTemplate.opsForSet().add("userNames","张三","张三","李四","王五"); Set<String> userNames = stringRedisTemplate.opsForSet().members("userNames"); Long size = stringRedisTemplate.opsForSet().size("userNames"); System.out.println(size); userNames.forEach(System.out::println); ~~~ ##### 5.3.5操作zSet 使用stringRedisTemplate.opsForZSet()操作的就是zSet类型 ~~~java stringRedisTemplate.opsForZSet().add("zsets", "java", 500); stringRedisTemplate.opsForZSet().add("zsets", "spring", 200); stringRedisTemplate.opsForZSet().add("zsets", "redis", 300); Set<String> zsets = stringRedisTemplate.opsForZSet().range("zsets", 0, -1); zsets.forEach(System.out::println); System.out.println("========================"); Set<ZSetOperations.TypedTuple<String>> zsets1 = stringRedisTemplate.opsForZSet().rangeByScoreWithScores("zsets",200,500); zsets1.forEach(item -> { System.out.println("item"+item); System.out.println(item.getValue()); System.out.println(item.getScore()); }); ~~~ ##### 5.3.6操作Hash 使用stringRedisTemplate.opsForHash()操作的就是hash类型 ~~~java stringRedisTemplate.opsForHash().put("maps","name","张三"); Object o = stringRedisTemplate.opsForHash().get("maps", "name"); System.out.println(o); Set<Object> name = stringRedisTemplate.opsForHash().keys("maps"); name.forEach(System.out::println); List<Object> maps = stringRedisTemplate.opsForHash().values("maps"); maps.forEach(System.out::println); ~~~ #### 5.4 RedisTemplate应用 RedisTemplate主要应用于存储的值是对象的情况,但如果使用对象,所有的对象都必须进行序列化才可以存储。 RedisTemplate存储的时候会对键和值进行序列化操作。 ##### 5.4.1 操作普通对象 ~~~java User u1 = new User("zs", 20, "15386880458"); redisTemplate.opsForValue().set("u1", u1); User user =(User) redisTemplate.opsForValue().get("u1"); System.out.println(user); ~~~ ##### 5.4.2 操作List ~~~java @Test public void test2() { User u1 = new User("zs", 20, "15386880458"); User u2 = new User("lisi", 20, "15386880458"); redisTemplate.opsForList().leftPush("users",u1); redisTemplate.opsForList().leftPush("users",u2); List userlist = redisTemplate.opsForList().range("users", 0, -1); userlist.forEach(System.out::println); } ~~~ ##### 5.4.3 操作Hash ~~~java @Test public void test4() { User u1 = new User(100, "lxd", 20); User u2 = new User(101, "cdp", 21); User u3 = new User(102, "luhui", 21); List<User> list = new ArrayList<>(); //从数据库中获取到集合数据 list.add(u1); list.add(u2); list.add(u3); redisTemplate.opsForHash().put("data", "userList", list); List<User> userList = (List<User>) redisTemplate.opsForHash().get("data", "userList"); for (User user : userList) { System.out.println(user); } } ~~~ ### 6. 自定义Template springboot项目整合Redis记录了RedisTemplate和StringRedisTemplate的使用效果,由于分别使用了不同的序列化器,所以在Redis中存储的形式也不相同。redisTemplate使用的是默认的序列化器jdk序列化方式,而StringRedisTemplate使用了String序列化方式,如果使用默认的这种序列化方式,存入redis中的key就变成带有转义字符的,这种情况就可以自定义RedisTemplate类,一般为了开发的方便,直接定义RedisTemplate<String, Object>类型,配置内容如下,企业实际开发中,直接可以使用: 使用的依赖,springboot已经集成,无需再导入 ~~~xml <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> ~~~ 配置类: ~~~java import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; 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.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { @Bean @SuppressWarnings("all") public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); //自定义Jackson序列化配置 Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); jsonRedisSerializer.setObjectMapper(objectMapper); //key使用String的序列化方式 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); template.setKeySerializer(stringRedisSerializer); //hash的key也是用String的序列化方式 template.setHashKeySerializer(stringRedisSerializer); //value的key使用jackson的序列化方式 template.setValueSerializer(jsonRedisSerializer); //hash的value也是用jackson的序列化方式 template.setHashValueSerializer(jsonRedisSerializer); template.afterPropertiesSet(); return template; } } ~~~
redis教程
最新推荐文章于 2024-10-17 15:35:43 发布