文章目录
1.概述
笔记小结:
- NoSQL:非关系型数据库,NoSQL数据库提供了一种不同的数据存储和查询模型。
- Redis特征:
- 键值(key-value)型,value支持多种不同数据结构,功能丰富
- 单线程,每个命令具备原子性(在Redis6.0中的网络部分是多线程的)
- 低延迟,速度快(基于内存、IO多路复用、良好的编码)。
- 支持数据持久化
- 支持主从集群、分片集群
- 支持多语言客户端
- Redis新特性:
- Redis Funcitons
- Client-eviction
- ACL v2
- Muti-part AOF
- ……
1.1NoSQL
NoSQL(Not Only SQL)是一种广义的数据库分类,它代表了一组非关系型数据库管理系统。相对于传统的关系型数据库(如SQL数据库),NoSQL数据库提供了一种不同的数据存储和查询模型。
说明:
- 关系型数据库存储的是结构化的数据,可以为每个元组或字段添加约束等条件
- 非关系型数据库存储的是非结构化的数据,通常来说是通过键值对的方式进行存储。存储的数据是多样的,可以是文档也可以是图
说明:
- 关系型数据库存储的数据,它们之间可以通过第三张表来建立关联
- 非关系型数据库存储的数据,它们之间是没有关联的
说明:
- 关系型数据库存储的数据,可以通过SQL语句来进行数据的增删改查
- 非关系型数据库存储的数据,它们各自有各自存储数据的方式,存储的规则各不相同
说明:
- 关系型数据库支持事务的ACID特性,原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)
- 非关系型数据库存储没有事务的说法
总的来说,SQL与NoSQL区别可概括为一张表:
1.2含义
Redis诞生于2009年全称是RemoteDictionaryServer,远程词典服务器,是一个基于内存的键值型NoSQL数据。
特征:
- 键值(key-value)型,value支持多种不同数据结构,功能丰富
- 单线程,每个命令具备原子性(在Redis6.0中的网络部分是多线程的)
- 低延迟,速度快(基于内存、IO多路复用、良好的编码)。
- 支持数据持久化
- 支持主从集群、分片集群
- 支持多语言客户端
1.3Redis新特性
Redis Funcitons
说明:
Redis函数,一种新的通过服务端脚本扩展Redis的方式,函数与数据本身一起存储。简言之,redis自己要去抢夺Lua脚本的饭碗
Client-eviction
说明:
对于连接Redis的人数和性能变为可配
Muti-part AOF
说明:
异步读写不再是痛点
ACL v2
说明:
精细化权限管理,可为集群配置密码等
listpack
说明:
listpack 是用来替代ziplist的新数据结构,在7.0版本已经没有ziplist 的配置了(6.0版本仅部分数据类型作为过渡阶段在使用)
2.基本用例
笔记小结:
安装并运行
在windows中……
在Docker容器中
sudo docker run --restart=always --log-opt max-size=100m --log-opt max-file=2 -p 6379:6379 --name myredis -v /home/redis/myredis/myredis.conf:/etc/redis/redis.conf -v /home/redis/myredis/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes --requirepass qweasdzxc
图形化界面使用……
常见命令
- String类型:
- 添加:SET、GET、MSET(mulitiple set)、MGET
- 修改:INCR(increase)、INCRBY(increase by)、INCRBYFLOAT(increase by float)、SETNX(set if not exist)、SETEX(set if expire)
- Hash类型:
- 添加:HSET、HGET、HMSET(hash mulitiple set )
- 修改:HINCRBY(hash increase)、HSETNX(hash set if not exist)
- 查询:HMGET(hash mulitiple get)、HGETALL、HKEYS、HVALS
- List类型:
- 添加:LPUSH 、RPUSH
- 删除:LPOP 、RPOP 、BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil
- 查询:LRANGE
- Set类型:
- 添加:SADD(set addtion)
- 删除:SREM(set remove member)
- 修改:SINTER (set intersection)、SUNION(set union) 、SDIFF(set different)
- 查询:SCARD (set cardinality)、SISMEMBER(set is member)、SMEMBERS(set members)
- SortedSet类型、BitMap类型、HyperLogLog类型、Stream类型、GEO类型:详细请查看
2.1安装并运行
2.1.1在Windows系统
步骤一:解压
说明:
安装完后会产生如下文件
启动示例:
步骤二:启动服务端
redis-server.exe redis.windows.conf
说明:
- 启动服务端时,需要指定redis配置文件
- 若未添加配置项,报错
注意:
需要添加conf配置项
步骤三:启动客户端
1.启动客户端
说明:
若启动了redis的服务端,但并未出现Running in standalone mode的提示字样,则需要打开客户端进行shutdown操作
# 通过cmd打开客户端 redis-cli.exe # 关闭客户端 shutdown
现在重启服务端即可
2.重启服务端
redis-server.exe redis.windows.conf
说明:
- 重启后成功
2.1.2在Docker容器中
步骤一:拉取Docker镜像
sudo docker pull redis
步骤二:启动服务端
sudo docker run --restart=always --log-opt max-size=100m --log-opt max-file=2 -p 6379:6379 --name myredis -v /home/redis/myredis/redis.conf:/etc/redis/redis.conf -v /home/redis/myredis/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes --requirepass qweasdzxc
说明:参数解释
sudo docker run
: 运行 Docker 容器的命令。--restart=always
: 设置容器在退出时自动重启。--log-opt max-size=100m
: 设置容器日志文件的最大大小为 100MB。--log-opt max-file=2
: 设置容器最多保留的日志文件数量为 2 个。-p 6379:6379
: 将容器的 Redis 服务端口映射到主机的 6379 端口。--name myredis
: 指定容器的名称为 “myredis”。-v /home/redis/myredis/redis.conf:/etc/redis/redis.conf
: 将主机上的 Redis 配置文件挂载到容器内的/etc/redis/redis.conf
路径。-v /home/redis/myredis/data:/data
: 将主机上的数据目录挂载到容器内的/data
路径,用于持久化 Redis 数据。-d redis
: 指定要运行的容器镜像为 “redis”,即 Redis 官方提供的镜像。redis-server /etc/redis/redis.conf
: 指定容器启动时要运行的 Redis 服务,并传递 Redis 配置文件路径。--appendonly yes
: 开启 Redis 的 AOF(Append Only File)持久化模式,将写操作追加到磁盘上的文件中。--requirepass qweasdzxc
: 设置 Redis 服务器的密码为 “qweasdzxc”,即需要密码才能访问 Redis 服务。
注意:
若需要开启Redis的远程访问服务,需要为Redis设置密码
步骤三:启动客户端
redis-cli [options] [commonds]
redis-cli -h 127.0.0.1 -p 6739 -a qweasdzxc
说明:参数解释
-h 127.0.0.1
:指定要连接的redis节点的IP地址,默认是127.0.0.1-p 6379
:指定要连接的redis节点的端口,默认是6379-a 123321
:指定redis的访问密码
补充:
ping
:与redis服务端做心跳测试,服务端正常会返回pong
2.1.3运行图形化界面客户端
步骤一:下载客户端
网址;lework/RedisDesktopManager-Windows: RedisDesktopManager Windows版本 (github.com)
说明:结果
步骤二:安装
说明:
安装失败,需要安装运行Visual C++的运行库即可
步骤三:运行
2.2常见命令
2.2.1概述
Redis是一个key-value的数据库,key一般是String类型,不过value的类型多种多样:
说明:
redis的数据类型有众多,现在依次介绍一下各个类型的命令
Redis为了方便我们学习,将操作不同数据类型的命令也做了分组,在官网( https://redis.io/commands )可以查看到不同的命令:
2.2.2通用命令
通用指令是部分数据类型的,都可以使用的指令,常见的有:
- KEYS:查看符合模板的所有key,不建议在生产环境设备上使用
- DEL:删除一个指定的key
- EXISTS:判断key是否存在
- EXPIRE:给一个key设置有效期,有效期到期时该key会被自动删除
- TTL:查看一个KEY的剩余有效期
说明:
keys
不建议在生产环境设备上使用,因为Redis为单线程,若需要查出的Key值很多,则会造成线程阻塞
补充:
- 通过help [command] 可以查看一个命令的具体用法,例如:
2.2.3String类型
2.2.3.1概述
String类型,也就是字符串类型,是Redis中最简单的存储类型。
其value是字符串,不过根据字符串的格式不同,又可以分为3类:
- string:普通字符串
- int:整数类型,可以做自增、自减操作
- float:浮点类型,可以做自增、自减操作
不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同。字符串类型的最大空间不能超过512m.
说明:
在String类型中,Redis底层可分为三种类型进行存储,分别是,字符串会转换为字节进行存储、数字和浮点数会转换为二进制进行存储
2.2.3.2常用命令
1.新增
- SET:添加或者修改已经存在的一个String类型的键值对
- GET:根据key获取String类型的value
- MSET(mulitiple set):批量添加多个String类型的键值对
- MGET(mulitiple get):根据多个key获取多个String类型的value
说明:
- 以上命令设置成功
2.自增长
- INCR(increase):让一个整型的key自增1
- INCRBY(increase by):让一个整型的key自增并指定步长,例如:incrby num 2 让num值自增2
- INCRBYFLOAT(increase by float):让一个浮点类型的数字自增并指定步长
说明:
- 当使用自增长后,数字会根据需要进行增加
3.组合命令
- SETNX(set if not exist):添加一个String类型的键值对,前提是这个key不存在,否则不执行
- SETEX(set if expire):添加一个String类型的键值对,并且指定有效期
说明:
- 若Redis中已存在该键,则设置失败
2.2.3.3key的结构
Redis的key允许有多个单词形成层级结构,多个单词之间用’:'隔开,格式如下:
项目名:业务名:类型:id
说明:
这个格式并非固定,也可以根据自己的需求来删除或添加词条。
例如我们的项目名称叫 heima,有user和product两种不同类型的数据,我们可以这样定义key:
user相关的key:heima:user:1 product相关的key:heima:product:1
如果Value是一个Java对象,例如一个User对象,则可以将对象序列化为JSON字符串后存储:
KEY | VALUE |
---|---|
heima:user:1 | ’ {“id”:1, “name”: “Jack”, “age”: 21} ’ |
heima:product:1 | ’ {“id”:1, “name”: “小米11”, “price”: 4999} ’ |
说明:
- 当使用了Redis
:
的分组方式后,可以看到可视化工具以及为我们创建好分组
2.2.4Hash类型
2.2.4.1概述
Hash类型,也叫散列,其value是一个无序字典,类似于Java中的HashMap结构。String结构是将对象序列化为JSON字符串后存储,当需要修改对象某个字段时很不方便:
Hash结构可以将对象中的每个字段独立存储,可以针对单个字段做CRUD:
2.2.4.2常见命令
1.新增
- HSET key field value:添加或者修改hash类型key的field的值
- HGET key field:获取一个hash类型key的field的值
- HMSET(hash mulitiple set ):批量添加多个hash类型key的field的值
说明:
HMSET
将被删除,因为效果同HSET
类似
2.自增长
- HINCRBY(hash increase):让一个hash类型key的字段值自增并指定步长
说明:
- 可以看到此处age值以及增长
3.组合命令
- HSETNX(hash set if not exist):添加一个hash类型的key的field值,前提是这个field不存在,否则不执行
说明:
- 此处key值为
ljtxy:product"1
的键已有age的filed域,因此设置失败
4.查询
- HMGET(hash mulitiple get):批量获取多个hash类型key的field的值
- HGETALL:获取一个hash类型的key中的所有的field和value
- HKEYS:获取一个hash类型的key中的所有的field
- HVALS:获取一个hash类型的key中的所有的value
2.2.5List类型
2.2.5.1概述
Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。
特征也与LinkedList类似:
- 有序
- 元素可以重复
- 插入和删除快
- 查询速度一般
常用来存储一个有序数据,例如:朋友圈点赞列表,评论列表等。
2.2.5.2常见命令
1.新增
- LPUSH key element … :向列表左侧插入一个或多个元素
- RPUSH key element … :向列表右侧插入一个或多个元素
说明:结果
2.删除
-
LPOP key:移除并返回列表左侧的第一个元素,没有则返回nil
-
RPOP key:移除并返回列表右侧的第一个元素
-
BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil
说明:
- 类似于等待指定延时时间,若超时则返回nil
3.查询
- LRANGE key star end:返回一段角标范围内的所有元素
说明:结果
2.2.6Set类型
2.2.6.1概述
Redis的Set结构与Java中的HashSet类似,可以看做是一个value为null的HashMap。因为也是一个hash表,因此具备与HashSet类似的特征:
- 无序
- 元素不可重复
- 查找快
- 支持交集、并集、差集等功能
2.2.6.2常见命令
1.新增
- SADD(set addtion) key member … :向set中添加一个或多个元素
2.删除
- SREM(set remove member) key member … : 移除set中的指定元素
3.交并差
- SINTER (set intersection)key1 key2 … :求key1与key2的交集
- SUNION(set union) key1 key2 …:求key1和key2的并集
- SDIFF(set different) key1 key2 … :求key1与key2的差集
说明:
4.查询
- SCARD (set cardinality)key: 返回set中元素的个数
- SISMEMBER(set is member) key member:判断一个元素是否存在于set中
- SMEMBERS(set members):获取set中的所有元素
2.2.7SortedSet类型
2.2.7.1概述
Redis的SortedSet是一个可排序的set集合,与Java中的TreeSet有些类似,但底层数据结构却差别很大。SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList)加 hash表。
SortedSet具备下列特性:
- 可排序
- 元素不重复
- 查询速度快
因为SortedSet的可排序特性,经常被用来实现排行榜这样的功能。
2.2.7.2常用命令
1.新增
- ZADD key score member [score member]:添加一个或多个元素到sorted set ,如果已经存在则更新其score值
说明:
- 新增值
2.删除
- ZREM key member:删除sorted set中的一个指定元素
说明:
- 删除值
3.交并差
- ZDIFF、ZINTER、ZUNION:求差集、交集、并集
3.查询
- ZSCORE key member : 获取sorted set中的指定元素的score值
- ZRANK key member:获取sorted set 中的指定元素的排名
- ZCARD key:获取sorted set中的元素个数
- ZCOUNT key min max:统计score值在给定范围内的所有元素的个数
- ZINCRBY key increment member:让sorted set中的指定元素自增,步长为指定的increment值
- ZRANGE key min max:按照score排序后,获取指定排名范围内的元素
说明:
- range表示返回相应的元素
- ZRANGEBYSCORE key min max:按照score排序后,获取指定score范围内的元素
说明;
- rangbyscore获取指定范围内排序后的元素
2.2.7.3应用场景
2.2.8BitMap类型
2.2.8.1概述
用String类型作为底层数据结构实现的一种统计二值状态的数据类型。位图本质是数组,它是基于String数据类型的按位的操作。该数组由多个二进制位组成,每个二进制位都对应一个偏移量(我们称之为一个索引)。Bitmap支持的最大位数是232位,它可以极大的节约存储空间,使用512M内存就可以存储多达42.9亿的字节信息(232= 4294967296)
2.2.8.2常用命令
1.新增
- setbit key offset value:添加一个元素到指定位置的值
说明:
- 新增值
2.查询
获取指定元素值
- getbit key offset:获取指定元素指定位置的值
说明:
- 查询值
获取指定元素存储字节
- strlen key:获取指定元素的存储字节数
说明:
- 查询占用空间
- bitcount key:获取指定元素的1的个数
说明:
- 查询1的个数
获取多个指定元素的位元存储:
- BITOP operation destkey key [key …]:获取多个位上的元素
说明:
补充:
BITOP AND destkey srckey1 srckey2 srckey3 ... srckeyN
,对一个或多个 key 求逻辑并,并将结果保存到 destkey 。BITOP OR destkey srckey1 srckey2 srckey3 ... srckeyN
,对一个或多个 key 求逻辑或,并将结果保存到 destkey 。BITOP XOR destkey srckey1 srckey2 srckey3 ... srckeyN
,对一个或多个 key 求逻辑异或,并将结果保存到 destkey 。BITOP NOT destkey srckey
,对给定 key 求逻辑非,并将结果保存到 destkey 。
2.2.8.3应用场景
统计用户签到的次数
2.2.9HyperLogLog类型
2.2.9.1概述
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
2.2.9.2常用命令
1.新增
- PFADD(Probabilistic Fixed Add) key element [element …]:添加指定元素到 HyperLogLog 中
说明:
- 新增元素
2.修改
- PFMERGE(Probabilistic Fixed Merger) destkey sourcekey [sourcekey …]:将多个 HyperLogLog 合并为一个 HyperLogLog
说明:
- 合并基数
3.查询
- PFCOUNT key [key …]:返回给定 HyperLogLog 的基数估算值
说明:
- 获得去重后的基础个数
2.2.9.3应用场景
统计商业网站的UA(用户访问次数)
2.2.10Stream类型
2.2.10.1概述
Stream 是 Redis 5.0 引入的一种新数据类型,可以实现一个功能非常完善的消息队列。
2.2.10.2常用命令
1.新增
- XADD key ID field value [field value …]:使用XADD向队列添加消息,如果指定的队列不存在,则创建队列
说明:
- 查看结果
- XGROUP [CREATE key groupname id-or-$]:创建消费者组
说明:
- 创建key为s1的消费者组g1,并且保留数据
- XGROUP [CREATECONSUMER key groupname consumername]:添加消费组中指定的消费者
说明:
- 指定key和消费组,为其添加消费者
- XPENDING key group [[IDLE min-idle-time] start end count [consumer]]:显示待处理消息的相关信息
说明:
- 返回所有为确认的消息
2.删除
- XGROUP [DESTROY key groupname]:使用XGROUP DESTROY 删除消费者组
说明:
- 指定key和消费组名
- XGROUP [DELCONSUMER key groupname consumername]:删除消费者组中的指定消费者
说明:
- 待实验
3.更新
- XACK key group ID [ ID …]:将消息标记为“已处理”
说明:
- 指定键和组名以及待处理的队列的ID
4.查询
- XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key …] id [id …]:使用XREAD以阻塞或非阻塞方式获取消息列表
说明:
- 查询元素
- 阻塞式读取最新消息
- XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key …] ID [ID …]:读取消费组中的消息
说明:
2.2.11GEO类型
2.2.11.1概述
GEO就是Geolocation的简写形式,代表地理坐标。Redis在3.2版本中加入了对GEO的支持,允许存储地理坐标信息,帮助我们根据经纬度来检索数据
2.2.11.2常见命令
1.新增
- GEOADD key [NX | XX] [CH] longitude latitude member :添加一个地理空间信息,包含:经度(longitude)、纬度(latitude)、值(member)
说明:
- 参数解释:
GEOADD 键 精度 维度 值
- GEOPOS key [member [member …]]:返回指定member的坐标
说明:
- 参数解释:
GEOPOS 键 成员
2.修改
- GEODIST key member1 member2 [M | KM | FT | MI]:计算指定的两个点之间的距离并返回
说明:
- 参数解释:
GEODIST 键 值1 值2
- GEOSEARCH key <FROMMEMBER member | FROMLONLAT longitude latitude> <BYRADIUS radius <M | KM | FT | MI> | BYBOX width height <M | KM | FT | MI>> [ASC | DESC] [COUNT count [ANY]] [WITHCOORD] [WITHDIST] [WITHHASH]:在指定范围内搜索member,并按照与指定点之间的距离排序后返回。范围可以是圆形或矩形。6.2.新功能
说明:
- 参数解释:
GEODIST 键 指定经纬度 画圆 举例 返回距离
- GEOHASH key [member [member …]]:将指定member的坐标转为hash字符串形式并返回
说明:
- 参数解释:
GEOHASH 键 成员
3.Redis的Java客户端
笔记小结:
- 概述:Redis官网中提供了各种语言的客户端,地址:https://redis.io/clients
- Jedis基本使用:Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗
- Jedis连接池:此时使用Jedis连接池代替Jedis的直连方式,减少频繁创建和销毁连接
- SpringDataRedis使用:SpringData是Spring中数据操作的模块,包含对各种数据库的集成
- RedisSerializr序列化:自定义序列化的方式让Redis存储资源更节省内存
- StringRedisTemplate使用:为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。
3.1概述
在Redis官网中提供了各种语言的客户端,地址:https://redis.io/clients
说明:
在Java客户端中中有很多优秀的客户端用法,这里推荐学习Jedis和Lettcuce
Spring对Java客户端的Jedis和lettuce操作进行了整合,叫Spring Data Redis,此时学习Spring Data Redis
3.2基本用例-Jedis使用
3.2.1概述
Jedis的官网地址: https://github.com/redis/jedis
3.2.2基本用例
步骤一:导入依赖
<!--jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.4.1</version>
</dependency>
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
步骤二:演示
public class JedisTest {
public Jedis jedis;
@Before
public void setUp() {
// 1.建立连接
jedis = new Jedis("10.13.164.55", 6379);
// 2.设置密码
jedis.auth("qweasdzxc");
// 3.选择库
jedis.select(0);
}
@Test
public void testSet() {
String set = jedis.set("yueyue2", "玥玥");
System.out.println(set);
String s = jedis.get("yueyue2");
System.out.println(s);
}
@After
public void setDown() {
if (Objects.isNull(jedis)) {
jedis.close();
}
}
}
说明:
创建Jedis对象、测试方法、关闭资源
3.2.3Jedis连接池
3.2.3.1概述
Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此我们推荐大家使用Jedis连接池代替Jedis的直连方式。
3.2.3.2基本用例
步骤一:创建工厂
/**
* 获取Jedis连接池工厂
*/
public class JedisConnectionFactory {
private static final JedisPool jedisPool;
static {
// 配置连接池
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大连接
jedisPoolConfig.setMaxTotal(8);
// 最大空闲连接,当有连接时,最多准备8个连接点
jedisPoolConfig.setMaxIdle(8);
// 最小空闲连接,当没有连接时,会释放所有连接点
jedisPoolConfig.setMinIdle(0);
// 设置最长等待时间,ms
jedisPoolConfig.setMaxWait(Duration.ofMillis(200));
// 创建连接此对象
jedisPool = new JedisPool(jedisPoolConfig, "10.13.164.55", 6379, 2000, "qweasdzxc");
}
// 获取Jedis对象
public static Jedis getJedis() {
return jedisPool.getResource();
}
}
步骤二:演示
public class JedisTest {
public Jedis jedis;
@Before
public void setUp() {
// 1.建立连接
// jedis = new Jedis("10.13.164.55", 6379);
// 2.设置密码
// jedis.auth("qweasdzxc");
jedis = JedisConnectionFactory.getJedis();
// 3.选择库
jedis.select(0);
}
@Test
public void testSet() {
String set = jedis.set("yueyue2", "玥玥");
System.out.println(set);
String s = jedis.get("yueyue2");
System.out.println(s);
}
@After
public void setDown() {
if (Objects.isNull(jedis)) {
jedis.close();
}
}
}
3.3基本用例-SpringDataRedis使用
3.3.1概述
SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:https://spring.io/projects/spring-data-redis
- 提供了对不同Redis客户端的整合(Lettuce和Jedis)
- 提供了RedisTemplate统一API来操作Redis
- 支持Redis的发布订阅模型
- 支持Redis哨兵和Redis集群
- 支持基于Lettuce的响应式编程
- 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化
- 支持基于Redis的JDKCollection实现
3.3.2基本用例
说明:常用命令操作
API 返回值类型 说明 redisTemplate.opsForValue() ValueOperations 操作String类型数据 redisTemplate.opsForHash() HashOperations 操作Hash类型数据 redisTemplate.opsForList() ListOperations 操作List类型数据 redisTemplate.opsForSet() SetOperations 操作Set类型数据 redisTemplate.opsForZSet() ZSetOperations 操作SortedSet类型数据 redisTemplate 通用的命令
步骤一:导入依赖
<dependencies>
<!--SpringDataRedis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
说明:
此实验在SpringBoot中操作,因此导入SpringBoot依赖
步骤二:添加配置
spring:
redis:
host: 10.13.164.55
port: 6379
password: qweasdzxc
lettuce: # redis默认使用lettuce客户端进行连接
pool:
max-active: 8 # 最大连接
min-idle: 0 # 最小空闲
max-idle: 8 # 最大空闲
max-wait: 200 # 连接等待时间
说明:
配置Redis的配置文件,便于SpringBoot进行自动装配
步骤三:演示
@SpringBootTest
class SpringDataRedisDemoApplicationTests {
@Autowired
RedisTemplate redisTemplate;
@Test
void contextLoads() {
redisTemplate.opsForValue().set("yueyue", "玥玥大美女");
Object o = redisTemplate.opsForValue().get("yueyue");
System.out.println(o.toString());
}
}
说明:
需要使用
@Autowired
注解实现依赖注入
注意:
RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的
这样做可读性会变差,并且内存占用较大
查看源码,发现底层会用ObjectOutputStream对象吧Java对象转换为字节
3.3.3RedisSerializr序列化
3.3.3.1概述
因为SpringDataRedis的序列化方式采用默认的JDK序列化,而不能达到我们存入数据得到所见及所得的方式,因此这里采用自定义序列化的方式进行
说明:
自定义序列化有多种实现方式,SpringDataRedis的序列化方式默认采用
JdkSerializationRedisSerializer
进行序列化。此处建议使用两种序列化方式,一种是字符串转换为字符串的序列化方式StringRedisSerializer
,另一种是Json与字符串互相转换的方式GenericJackson2JsonRedisSerializer
3.3.3.2基本用例
步骤一:自定义序列化
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
// 创建Template
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 设置连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer =
new GenericJackson2JsonRedisSerializer();
// key和 hashKey采用 string序列化
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
// value和 hashValue采用 JSON序列化
redisTemplate.setValueSerializer(jsonRedisSerializer);
redisTemplate.setHashValueSerializer(jsonRedisSerializer);
return redisTemplate;
}
说明:
- 此时完成RedisTemplate的依赖注入,并重新写入自己的逻辑即可
- 连接工厂,SpringBoot框架会帮我们自动完成注入,因此这里直接使用连接工厂
步骤二:演示
@SpringBootTest
class SpringDataRedisDemoApplicationTests {
@Autowired
RedisTemplate<String, Object> redisTemplate;
@Test
void testString() {
redisTemplate.opsForValue().set("yueyue", "玥玥,大美女");
Object o = redisTemplate.opsForValue().get("yueyue");
System.out.println(o.toString());
}
@Test
void testObject() {
redisTemplate.opsForValue().set("yueyue", new User("玥玥", 17, "大美女"));
Object o = redisTemplate.opsForValue().get("yueyue");
System.out.println(o.toString());
}
}
说明:
- testString方法结果如下
- testObject方法结果如下
注意:
每次存储对象值的时候,SpringDataRedis为了实现自动的序列化与反序列化,会加入一串很长的全路径类名,因此会占用大量的内存空间
3.3.4StringRedisTemplate使用
3.3.4.1概述
为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。
说明:
手动完成对象的序列化和反序列化,虽然麻烦,但可以节省内存空间
3.3.4.2基本用例
步骤一:导入依赖
<!--SpringDataRedis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.33</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
步骤二:演示
@SpringBootTest
class SpringDataRedisDemoApplicationTests2 {
@Autowired
StringRedisTemplate stringRedisTemplate;
@Test
void testString() {
stringRedisTemplate.opsForValue().set("yueyue", "玥玥,大美女");
Object o = stringRedisTemplate.opsForValue().get("yueyue");
System.out.println(o.toString());
}
@Test
void testObject() {
User user = new User("玥玥", 17, "大美女");
String jsonString = JSON.toJSONString(user); // 此处使用fastJson工具进行对象的序列化与反序列化
stringRedisTemplate.opsForValue().set("yueyue", jsonString);
String result = stringRedisTemplate.opsForValue().get("yueyue");
User resultUser = JSON.parseObject(result, User.class);
System.out.println(resultUser);
}
}
说明:
testString方法结果如下
testObject方法结果如下