电白网站建设,ppt做的好的网站有哪些内容,华强北做电子网站建设,器材管理网站开发2022黑马Redis跟学笔记.基础篇 一1.Redis入门1.1.认识NoSQL1.1.1.结构化与非结构化1.1.2.关联和非关联1.1.3.查询方式1.1.4.事务1.1.5.总结1.2.认识Redis1.3.安装Redis步骤一#xff1a;安装Redis依赖步骤二#xff1a;上传安装包并解压步骤三#xff1a;启动(1).默认启动(2…
2022黑马Redis跟学笔记.基础篇 一1.Redis入门1.1.认识NoSQL1.1.1.结构化与非结构化1.1.2.关联和非关联1.1.3.查询方式1.1.4.事务1.1.5.总结1.2.认识Redis1.3.安装Redis步骤一安装Redis依赖步骤二上传安装包并解压步骤三启动(1).默认启动(2).指定配置启动(3).开机自启Redis客户端(1).Redis命令行客户端(2).图形化桌面客户端安装建立连接2.Redis常见命令2.1.Redis数据结构介绍2.2.Redis通用命令2.2.1KEYS2.2.2 DEL2.2.3 EXISTS2.2.4 EXPIRE2.2.5 TTL2.3.String类型2.3.1.String的常见命令set字典帮助msetmgetincrincrbyincrbyfloatsetnxsetex2.3.2.Key结构2.4.Hash类型HSETHGETHMSETHMGETHGETALLHKEYSHVALSHINCRBYHSETNX2.5.List类型LPUSHLPOPRPUSHRPOPLRANGEBLPOP和BRPOP2.6.Set类型SADDSREMSCARDSISMEMBERSMEMBERSSINTERSDIFFSUNION2.7.SortedSet类型3.Redis的Java客户端3.1.Jedis快速入门3.2.Jedis连接池3.3.SpringDataRedis客户端3.3.1.SpringDataRedis快速入门(1.引入依赖(2.配置Redis(3.注入RedisTemplate(4.编写测试3.4.SpringDataRedis快速入门3.5.StringRedisTemplate处理String类型处理实体类类型处理Hash类型基础课程大纲
1.Redis入门
Redis是一种键值型的NoSql数据库这里有两个关键字
键值型NoSql
其中键值型是指Redis中存储的数据都是以key、value对的形式存储而value的形式多种多样可以是字符串、数值、甚至json 而NoSql则是相对于传统关系型数据库而言有很大差异的一种数据库。 对于存储的数据没有类似Mysql那么严格的约束比如唯一性是否可以为null等等所以我们把这种松散结构的数据库称之为NoSQL数据库。
1.1.认识NoSQL NoSql可以翻译做Not Only Sql不仅仅是SQL或者是No Sql非Sql的数据库。是相对于传统关系型数据库而言有很大差异的一种特殊的数据库因此也称之为非关系型数据库。
1.1.1.结构化与非结构化
传统关系型数据库是结构化数据每一张表都有严格的约束信息字段名、字段数据类型、字段约束等等信息插入的数据必须遵守这些约束
而NoSql则对数据库格式没有严格约束往往形式松散自由。
可以是键值型 也可以是文档型
甚至可以是图格式 1.1.2.关联和非关联
传统数据库的表与表之间往往存在关联例如外键
而非关系型数据库不存在关联关系要维护关系要么靠代码中的业务逻辑要么靠数据之间的耦合
{id: 1,name: 张三,orders: [{id: 1,item: {id: 10, title: 荣耀6, price: 4999}},{id: 2,item: {id: 20, title: 小米11, price: 3999}}]
}此处要维护“张三”的订单与商品“荣耀”和“小米11”的关系不得不冗余的将这两个商品保存在张三的订单文档中不够优雅。还是建议用业务来维护关联关系。
1.1.3.查询方式
传统关系型数据库会基于Sql语句做查询语法有统一标准
而不同的非关系数据库查询语法差异极大五花八门各种各样。 1.1.4.事务
传统关系型数据库能满足事务ACID的原则。
而非关系型数据库往往不支持事务或者不能严格保证ACID的特性只能实现基本的一致性。
1.1.5.总结
除了上述四点以外在存储方式、扩展性、查询性能上关系型与非关系型也都有着显著差异总结如下 存储方式 关系型数据库基于磁盘进行存储会有大量的磁盘IO对性能有一定影响。非关系型数据库他们的操作更多的是依赖于内存来操作内存的读写速度会非常快性能自然会好一些。
扩展性 关系型数据库集群模式一般是主从主从数据一致起到数据备份的作用称为垂直扩展。非关系型数据库可以将数据拆分存储在不同机器上可以保存海量数据解决内存大小有限的问题。称为水平扩展。关系型数据库因为表之间存在关联关系如果做水平扩展会给数据查询带来很多麻烦。
1.2.认识Redis
Redis诞生于2009年全称是Remote Dictionary Server 远程词典服务器是一个基于内存的键值型NoSQL数据库。
特征
键值key-value型value支持多种不同数据结构功能丰富单线程每个命令具备原子性低延迟速度快基于内存、IO多路复用、良好的编码。支持数据持久化支持主从集群、分片集群支持多语言客户端
作者Antirez
Redis的官方网站地址Redis官网
1.3.安装Redis
大多数企业都是基于Linux服务器来部署项目而且Redis官方也没有提供Windows版本的安装包。因此课程中我们会基于Linux系统来安装Redis.
此处选择的Linux版本为CentOS 7.
步骤一安装Redis依赖
Redis是基于C语言编写的因此首先需要安装Redis所需要的gcc依赖 首先用命令,可以看下系统是否有gcc环境
gcc -v有如下版本说明有了相关依赖。 如果没有依赖则执行如下命令
yum install -y gcc tcl步骤二上传安装包并解压
注意先安装vm-tools 如果没有安装配置共享文件夹是没有显示的。 新建共享文件夹把redis上传至共享文件夹中 解压到/usr/local/src 目录
tar -zxvf redis-6.2.6.tar.gz -C/usr/local/src进入redis目录
cd redis-6.2.6运行编译命令
make make install如果没有出错应该就安装成功了。 默认的安装路径是在 /usr/local/bin目录下
步骤三启动
redis的启动方式有很多种例如
默认启动指定配置启动开机自启
(1).默认启动
安装完成后在任意目录输入redis-server命令即可启动Redis
redis-server如图 这种启动属于前台启动会阻塞整个会话窗口窗口关闭或者按下CTRL C则Redis停止。不推荐使用。
(2).指定配置启动
如果要让Redis以后台方式启动则必须修改Redis配置文件就在我们之前解压的redis安装包下/usr/local/src/redis-6.2.6名字叫redis.conf 我们先将这个配置文件备份一份
cp redis.conf redis.conf.bck然后修改redis.conf文件中的一些配置 进入编辑器
vim redis.confRedis常见配置
# 监听的地址默认是127.0.0.1会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程修改为yes后即可后台运行
daemonize yes
# 密码设置后访问Redis必须输入密码
requirepass 123321更改监听地址 更改守护进程 更改密码
Redis的其它常见配置
# 监听的端口
port 6379
# 工作目录默认是当前目录也就是运行redis-server时的命令日志、持久化等文件会保存在这个目录
dir .
# 数据库数量设置为1代表只使用1个库默认有16个库编号0~15
databases 1
# 设置redis能够使用的最大内存
maxmemory 512mb
# 日志文件默认为空不记录日志可以指定日志文件名
logfile redis.log记录日志
启动Redis
# 进入redis安装目录
cd /usr/local/src/redis-6.2.6
# 启动
redis-server redis.conf查看redis是否成功允许
ps -ef | grep redis有进程在运行说明启动成功
停止服务 杀死进程即可
kill -9 72638另一种方式
# 利用redis-cli来执行 shutdown 命令即可停止 Redis 服务
# 因为之前配置了密码因此需要通过 -u 来指定密码
redis-cli -u 123321 shutdown(3).开机自启
我们也可以通过配置来实现开机自启。
首先新建一个系统服务文件
vi /etc/systemd/system/redis.service内容如下
[Unit]
Descriptionredis-server
Afternetwork.target[Service]
Typeforking
ExecStart/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf
PrivateTmptrue[Install]
WantedBymulti-user.target然后重载系统服务
systemctl daemon-reload现在我们可以用下面这组命令来操作redis了
# 启动
systemctl start redis
# 停止
systemctl stop redis
# 重启
systemctl restart redis
# 查看状态
systemctl status redis启动redis 停止redis
执行下面的命令可以让redis开机自启
systemctl enable redisRedis客户端
安装完成Redis我们就可以操作Redis实现数据的CRUD了。这需要用到Redis客户端包括
命令行客户端图形化桌面客户端编程客户端
(1).Redis命令行客户端
Redis安装完成后就自带了命令行客户端redis-cli 使用方式如下
redis-cli [options] [commonds]其中常见的options有
-h 127.0.0.1指定要连接的redis节点的IP地址默认是127.0.0.1-p 6379指定要连接的redis节点的端口默认是6379-a 123321指定redis的访问密码
其中的commonds就是Redis的操作命令例如
ping与redis服务端做心跳测试服务端正常会返回pong
不指定commond时会进入redis-cli的交互控制台
输入
redis-cli -h 127.0.0.1 -p 6379进入后输入
ping发现没有权限 于是我们增加密码
redis-cli -h 127.0.0.1 -p 6379 -a 123321再ping就成功了 这里提示我们这样连接输入秘密不安全 于是我们通过下面的方式 不输入密码连接
redis-cli -h 127.0.0.1 -p 6379之后输入密码连接
AUTH 123321连接成功后可以简单操作一些命令
set name jackget name(2).图形化桌面客户端
GitHub上的大神编写了Redis的图形化桌面客户端地址 RedisDesktopManager
不过该仓库提供的是RedisDesktopManager的源码并未提供windows安装包。
在下面这个仓库可以找到安装包 RedisDesktopManager-Windows 安装
在课前资料中可以找到Redis的图形化桌面客户端 解压缩后运行安装程序即可安装 此处略。
安装完成后在安装目录下找到rdm.exe文件
建立连接
建立连接前先关闭CenOS的防火墙
systemctl stop firewalld然后查询虚拟机的ip
ifconfig点击左上角的连接到Redis服务器按钮
在弹出的窗口中填写Redis服务信息
配置设置注意这里的地址填写虚拟机的ip地址这里的密码填写redis的密码用户名一定不要填 点击确定后在左下侧菜单有测试连接 点击即可建立连接了
Redis默认有16个仓库编号从0至15. 通过配置文件可以设置仓库数量但是不超过16并且不能自定义仓库名称。 在db1中加入一个键name 值是Rose
如果是基于redis-cli连接Redis服务可以通过select命令来选择数据库
# 选择 1号库
select 1结果如下 初学Redis建议用命令行不要用图形化界面
2.Redis常见命令
2.1.Redis数据结构介绍
Redis是典型的key-value数据库key一般是字符串而value包含很多不同的数据类型
Redis为了方便我们学习将操作不同数据类型的命令也做了分组在官网 redis官网 可以查看到不同的命令 不同类型的命令称为一个group我们也可以通过help命令来查看各种不同group的命令
接下来我们就学习常见的五种基本数据类型的相关命令。
2.2.Redis通用命令
通用指令是部分数据类型的都可以使用的指令常见的有
KEYS查看符合模板的所有keyDEL删除一个指定的keyEXISTS判断key是否存在EXPIRE给一个key设置有效期有效期到期时该key会被自动删除TTL查看一个KEY的剩余有效期
通过help [command] 可以查看一个命令的具体用法例如
# 查看keys命令的帮助信息
127.0.0.1:6379 help keysKEYS pattern
summary: Find all keys matching the given pattern
since: 1.0.0
group: generic2.2.1KEYS
不建议在生产环境设备上使用
KEYS查看符合模板的所有key
比如查询n开头的键
keys n*2.2.2 DEL
DEL删除一个指定的key 删除单值
del name删除多组键值对
del k1 k2 k3 k42.2.3 EXISTS
EXISTS判断key是否存在存在返回1不存在返回0
exists age
exists name2.2.4 EXPIRE
EXPIRE给一个key设置有效期有效期到期时该key会被自动删除
比如短信验证码是5分钟到期了自动删除不占用空间
expire age 202.2.5 TTL
TTL查看一个KEY的剩余有效期
TTL age那我们如果没有设置expire的话剩余时间是多少呢
TTL name得出结论 Redis中一般都设置有效期以免占用过多内存空间
2.3.String类型
String类型也就是字符串类型是Redis中最简单的存储类型。 其value是字符串不过根据字符串的格式不同又可以分为3类
string普通字符串int整数类型可以做自增、自减操作float浮点类型可以做自增、自减操作
不管是哪种格式底层都是字节数组形式存储只不过是编码方式不同。字符串类型的最大空间不能超过512m
2.3.1.String的常见命令
String的常见命令有
SET添加或者修改已经存在的一个String类型的键值对GET根据key获取String类型的valueMSET批量添加多个String类型的键值对MGET根据多个key获取多个String类型的valueINCR让一个整型的key自增1INCRBY:让一个整型的key自增并指定步长例如incrby num 2 让num值自增2INCRBYFLOAT让一个浮点类型的数字自增并指定步长SETNX添加一个String类型的键值对前提是这个key不存在否则不执行SETEX添加一个String类型的键值对并且指定有效期
set字典帮助 多次set会覆盖
mset
字典帮助
MSET k1 v1 k2 v2 k3 v3mget
字典帮助
MGET name k1 k2 k3incr
字典帮助
incr ageincrby
字典帮助
incrby age 2自减的话只需要改成负数即可
incrby age -2或者
decrby age 2incrbyfloat
字典帮助 这里存在小数位数异常的问题看这里 incrbyfloat小数位数异常问题
setnx
字典帮助
set name2 brank设置新属性name2 属性存在就插入失败
set 属性名 属性值 nx setnx 属性名 属性值
set color red nxsetex
字典帮助 添加并且设置有效期
setex medicine 20 lianhuaset 属性名 属性值 ex 秒数 setex 属性名 秒数 属性值
set money 10 ex 202.3.2.Key结构
Redis没有类似MySQL中的Table的概念我们该如何区分不同类型的key呢
思考例如需要存储用户、商品信息到redis有一个用户id是1有一个商品id恰好也是1此时如果使用id作为key那就会冲突了该怎么办
我们可以通过给key添加前缀加以区分不过这个前缀不是随便加的有一定的规范
Redis的key允许有多个单词形成层级结构多个单词之间用’:隔开格式如下 项目名:业务名:类型:id这个格式并非固定也可以根据自己的需求来删除或添加词条。这样以来我们就可以把不同类型的数据区分开了。从而避免了key的冲突问题。
例如我们的项目名称叫 heima有user和product两种不同类型的数据我们可以这样定义key user相关的keyheima:user:1 product相关的keyheima:product:1
如果Value是一个Java对象例如一个User对象则可以将对象序列化为JSON字符串后存储
KEYVALUEheima:user:1{“id”:1, “name”: “Jack”, “age”: 21}heima:product:1{“id”:1, “name”: “小米11”, “price”: 4999}
并且在Redis的桌面客户端中还会以相同前缀作为层级结构让数据看起来层次分明关系清晰 set heima:user:1 {id:1, name:Jack, age: 21}
set heima:user:2 {id:2, name:Rose, age: 18}
set heima:product:1 {id:1, name:小米11, price: 4999}
set heima:product:2 {id:2, name:荣耀6, price: 2999}从命令终端中看不出太大的差别 我们用图形界面端看一下heima和product形成了层级结构
2.4.Hash类型
Hash类型也叫散列其value是一个无序字典类似于Java中的HashMap结构。
String结构是将对象序列化为JSON字符串后存储当需要修改对象某个字段时很不方便 Hash结构可以将对象中的每个字段独立存储可以针对单个字段做CRUD Hash的常见命令有 HSET key field value添加或者修改hash类型key的field的值 HGET key field获取一个hash类型key的field的值 HMSET批量添加多个hash类型key的field的值 HMGET批量获取多个hash类型key的field的值 HGETALL获取一个hash类型的key中的所有的field和value HKEYS获取一个hash类型的key中的所有的field HINCRBY:让一个hash类型key的字段值自增并指定步长 HSETNX添加一个hash类型的key的field值前提是这个field不存在否则不执行
HSET
HSET key field value添加或者修改hash类型key的field的值
hset heima:user:3 name Lily
hset heima:user:3 age 21看一下图形界面 修改一个值以年龄为例
hset heima:user:3 age 17HGET
HGET key field获取一个hash类型key的field的值
hget heima:user:3 age
hget heima:user:3 nameHMSET
HMSET批量添加多个hash类型key的field的值
hmset heima:user:4 name HanMeiMei
hmset heima:user:4 name LiLei age 20 sex manHMGET
HMGET批量获取多个hash类型key的field的值
hmget heima:user:4 name age sexHGETALL
HGETALL获取一个hash类型的key中的所有的field和value
hgetall heima:user:4HKEYS
HKEYS获取一个hash类型的key中的所有的field
hkeys heima:user:4HVALS
HVALS获取一个hash类型的key中的所有的field所对应的value
hvals heima:user:4HINCRBY
HINCRBY:让一个hash类型key的字段值自增并指定步长
hincrby heima:user:4 age 2hincrby heima:user:4 age -2HSETNX
HSETNX添加一个hash类型的key的field值前提是这个field不存在否则不执行。
hsetnx heima:user:3 sex woman2.5.List类型
Redis中的List类型与Java中的LinkedList类似可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。
特征也与LinkedList类似
有序元素可以重复插入和删除快查询速度一般
常用来存储一个有序数据例如朋友圈点赞列表评论列表等。
List的常见命令有
LPUSH key element … 向列表左侧插入一个或多个元素LPOP key移除并返回列表左侧的第一个元素没有则返回nilRPUSH key element … 向列表右侧插入一个或多个元素RPOP key移除并返回列表右侧的第一个元素LRANGE key star end返回一段角标范围内的所有元素BLPOP和BRPOP与LPOP和RPOP类似只不过在没有元素时等待指定时间而不是直接返回 nil
LPUSH
LPUSH key element … 向列表左侧插入一个或多个元素 LPUSH users 1 2 3我们想想图形化界面中数据的存储结构是什么样的呢发现是倒叙
LPOP
LPOP key移除并返回列表左侧的第一个元素没有则返回nil
LPOP users 3RPUSH
RPUSH key element … 向列表右侧插入一个或多个元素
RPUSH users 4 5 6在图形界面中的结构如下
RPOP
RPOP key移除并返回列表右侧的第一个元素
RPOP users 3元素全移除完之后变成nil
LRANGE
LRANGE key star end返回一段角标范围内的所有元素(只是返回并不删除)
LRANGE users 2 5BLPOP和BRPOP
BLPOP和BRPOP与LPOP和RPOP类似只不过在没有元素时等待指定时间而不是直接返回 nil
BLPOP users 100打开另一个XShell客户端进入Redis给users2插入数据 最终结果如下 再看另外一个指令
BRPOP users3 100登入另一个客户端Redis插入数据 最终结果是 栈先进后出(入口和出口在一起)
RPUSH stack 1 2 3RPOP stack队列先进先出(入口和出口不在一起)
LPUSH line 4 5 6RPOP line 3阻塞队列
BRPOP blockline 3 100在另一个redis客户端插入
LPUSH blockline 4 5 6第一个客户端输出4先进先出
2.6.Set类型
Redis的Set结构与Java中的HashSet类似可以看做是一个value为null的HashMap。因为也是一个hash表因此具备与HashSet类似的特征 无序 元素不可重复 查找快 支持交集、并集、差集等功能
Set的常见命令有
SADD key member … 向set中添加一个或多个元素SREM key member … : 移除set中的指定元素SCARD key 返回set中元素的个数SISMEMBER key member判断一个元素是否存在于set中SMEMBERS获取set中的所有元素SINTER key1 key2 … 求key1与key2的交集
SADD
SADD key member … 向set中添加一个或多个元素
SADD set1 a b c查看set集合中的全部元素
SMEMBERS set1SREM
SREM key member : 移除set中的指定元素
SREM set1 aSCARD
SCARD key 返回set中元素的个数
SCARD set1SISMEMBER
SISMEMBER key member判断一个元素是否存在于set中
SISMEMBER set1 aSMEMBERS
SMEMBERS获取set中的所有元素
SMEMBERS set1SINTER
SINTER key1 key2 … 求key1与key2的交集 例如两个集合s1和s2:
求交集SINTER s1 s2
SINTER set1 set2SDIFF
求s1与s2的不同SDIFF s1 s2 求s1和s2的差集,s1有而s2没有比如下图的A部分。 SDIFF set1 set2SUNION
求key1和key2的并集
SUNION set1 set2练习
将下列数据用Redis的Set集合来存储
张三的好友有李四、王五、赵六李四的好友有王五、麻子、二狗
SADD zhangsan_friend lisi wangwu zhaoliu
SADD lisi_friend wangwu mazi ergou利用Set的命令实现下列功能
计算张三的好友有几人
SCARD zhangsan_friend计算张三和李四有哪些共同好友
SINTER zhangsan_friend lisi_friend查询哪些人是张三的好友却不是李四的好友
SDIFF zhangsan_friend lisi_friend查询张三和李四的好友总共有哪些人
SUNION zhangsan_friend lisi_friend判断李四是否是张三的好友
SISMEMBER zhangsan_friend lisi判断张三是否是李四的好友
SISMEMBER lisi_friend zhangsan将李四从张三的好友列表中移除
SREM zhangsan_friend lisi2.7.SortedSet类型
Redis的SortedSet是一个可排序的set集合与Java中的TreeSet有些类似但底层数据结构却差别很大。SortedSet中的每一个元素都带有一个score属性可以基于score属性对元素排序底层的实现是一个跳表SkipList加 hash表。
SortedSet具备下列特性
可排序元素不重复查询速度快
因为SortedSet的可排序特性经常被用来实现排行榜这样的功能。
SortedSet的常见命令有
ZADD key score member添加一个或多个元素到sorted set 如果已经存在则更新其score值ZREM key member删除sorted set中的一个指定元素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排序后获取指定排名范围内的元素ZRANGEBYSCORE key min max按照score排序后获取指定score范围内的元素ZDIFF、ZINTER、ZUNION求差集、交集、并集
注意所有的排名默认都是升序如果要降序则在命令的Z后面添加REV即可例如 升序获取sorted set 中的指定元素的排名ZRANK key member 降序获取sorted set 中的指定元素的排名ZREVRANK key memeber
练习题
将班级的下列学生得分存入Redis的SortedSet中
Jack 85, Lucy 89, Rose 82, Tom 95, Jerry 78, Amy 92, Miles 76
ZADD student 85 Jack 89 Lucy 82 Rose 95 Tom 78 Jerry 92 Amy 76 Miles并实现下列功能
删除Tom同学
ZREM student Tom获取Amy同学的分数
ZSCORE student Amy获取Rose同学的排名先看升序的排序
ZRANK student Rose再看降序的排序
ZREVRANK student Rose查询80分以下有几个学生
ZCOUNT student 0 80给Amy同学加2分
ZINCRBY student 2 Amy查出成绩前3名的同学
ZREVRANGE student 0 2查出成绩80分以下的所有同学
ZRANGEBYSCORE student 0 803.Redis的Java客户端
在Redis官网中提供了各种语言的客户端地址Redis-Java客户端 其中Java客户端也包含很多 标记为❤的就是推荐使用的java客户端包括 Jedis 以Redi s命令作为方法名称学习成本低简单实用。 但是Jedis实例是线程不安全的多线程环境下需要基于连接池来使用。 lettuceLettuce是基于Netty实现的支持同步、异步和响 应式编程方式并且是线程安全的。支持Redis的哨兵模式、集群模式和管道模式。 Jedis和Lettuce这两个主要是提供了Redis命令对应的API方便我们操作Redis而SpringDataRedis又对这两种做了抽象和封装因此我们后期会直接以SpringDataRedis来学习。 Redisson是在Redis基础上实现了分布式的可伸缩的java数据结构例如Map、Queue等而且支持跨进程的同步机制Lock、Semaphore等待比较适合用来实现特殊的功能需求。 3.1.Jedis快速入门
Jedis的官网地址 Jedis官网
我们先来个快速入门 创建工程:jedis-demo GroupId:com.heima Artifactid:jedis-demo 设置坐标 设置编码 配置Maven 设置save actions 1引入依赖
!--jedis--
dependencygroupIdredis.clients/groupIdartifactIdjedis/artifactIdversion3.7.0/version
/dependency
!--单元测试--
dependencygroupIdorg.junit.jupiter/groupIdartifactIdjunit-jupiter/artifactIdversion5.7.0/versionscopetest/scope
/dependency2建立连接
新建一个单元测试类com/itheima/test/JedisTest.java
内容如下 JedisTest.java
private Jedis jedis;BeforeEach
void setUp() {// 1.建立连接jedis new Jedis(192.168.150.101, 6379);// jedis JedisConnectionFactory.getJedis();// 2.设置密码jedis.auth(123321);// 3.选择库jedis.select(0);
}3测试 JedisTest.java
Test
void testString() {// 存入数据String result jedis.set(cup, green);System.out.println(result: result);String cup jedis.get(cup);System.out.println(cup: cup);
}Test
void testHash() {// 插入hash数据jedis.hset(cup:2, color, yellow);jedis.hset(cup:3, color, red);// 获取MapString, String map jedis.hgetAll(cup:2);System.out.println(map);
}4释放资源
AfterEach
void tearDown() {if (jedis ! null) {jedis.close();}
}String测试结果 Hash测试结果
3.2.Jedis连接池
Jedis本身是线程不安全的并且频繁的创建和销毁连接会有性能损耗因此我们推荐大家使用Jedis连接池代替Jedis的直连方式。 创建类 JedisConnectionFactory.java
package com.heima.jedis.util;import redis.clients.jedis.*;public class JedisConnectionFactory {private static JedisPool jedisPool;static {// 配置连接池JedisPoolConfig poolConfig new JedisPoolConfig();poolConfig.setMaxTotal(8);poolConfig.setMaxIdle(8);poolConfig.setMinIdle(0);poolConfig.setMaxWaitMillis(1000); // -1 是无限等待// 创建连接池对象参数连接池配置、服务端ip、服务端端口、超时时间、密码jedisPool new JedisPool(poolConfig, 192.168.150.101, 6379, 1000, 123321);}public static Jedis getJedis(){return jedisPool.getResource();}
}修改类JedisTest.java通过工厂模式获取连接池
private Jedis jedis;BeforeEach
void setUp() {// 1.建立连接jedis JedisConnectionFactory.getJedis();// 2.设置密码jedis.auth(123321);// 3.选择库jedis.select(0);
}我们看一下源码通过连接池方式获取的连接不会直接关闭而是放回连接池 源码可以看出Jedis只支持字符串和字节数组
最后再运行一下测试类JedisTest.java看看效果
3.3.SpringDataRedis客户端
SpringData是Spring中数据操作的模块包含对各种数据库的集成其中对Redis的集成模块就叫做SpringDataRedis官网地址spring-data-redis
提供了对不同Redis客户端的整合Lettuce和Jedis提供了RedisTemplate统一API来操作Redis支持Redis的发布订阅模型支持Redis哨兵和Redis集群支持基于Lettuce的响应式编程支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化支持基于Redis的JDKCollection实现
SpringDataRedis中提供了RedisTemplate工具类其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中
3.3.1.SpringDataRedis快速入门
SpringBoot已经提供了对SpringDataRedis的支持使用非常简单。
首先新建一个maven项目然后按照下面步骤执行 Group:com.heima Artifct:redis-demo 勾选依赖 设置编码 配置Maven 配置JDK 设置Save Action (1.引入依赖
增加连接池的依赖 !-- 连接池 --dependencygroupIdorg.apache.commons/groupIdartifactIdcommons-pool2/artifactId/dependency(2.配置Redis
编写application.yml
spring:redis:host: 192.168.150.101port: 6379password: 123321lettuce:pool:max-active: 8max-idle: 8min-idle: 0max-wait: 100ms注意默认是lettuce
(3.注入RedisTemplate
因为有了SpringBoot的自动装配我们可以拿来就用 RedisDemoApplicationTests.java
SpringBootTest
class RedisStringTests {Autowired(required false)private RedisTemplate redisTemplate;
}(4.编写测试
RedisDemoApplicationTests
SpringBootTest
class RedisDemoApplicationTests {Autowired(required false)private RedisTemplate redisTemplate;Testvoid testString() {redisTemplate.opsForValue().set(tomato,red);Object tomato redisTemplate.opsForValue().get(tomato);System.out.println(tomato: tomato);}
}运行测试类的结果 我们到XShell中看一下存取的字段发现是一段乱码 引出了下面的问题。
3.4.SpringDataRedis快速入门
RedisTemplate可以接收任意Object作为值写入Redis 只不过写入前会把Object序列化为字节形式默认是采用JDK序列化得到的结果是这样的 缺点
可读性差内存占用较大
而为啥默认是序列化我们看一下源码在set方法上打上断点 进入this.rawValue方法 看rawValue方法 进入serialize方法发现调用的是序列化writObject所以出现了乱码 那我们必须重写RedisTemplate 其中返回类型是RedisSerializer 我们看下RedisSerializer
我们可以自定义RedisTemplate的序列化方式代码如下
Configuration
public class RedisConfig {Beanpublic RedisTemplateString,Object redisTemplate(RedisConnectionFactory connectionFactory){// 创建RedisTemplate对象RedisTemplateString, Object template new RedisTemplate();// 设置连接工厂template.setConnectionFactory(connectionFactory);// 创建JSON序列化工具GenericJackson2JsonRedisSerializer jsonRedisSerializer new GenericJackson2JsonRedisSerializer();// 设置Key的序列化template.setKeySerializer(RedisSerializer.string());template.setHashKeySerializer(RedisSerializer.string());// 设置Value的序列化template.setValueSerializer(jsonRedisSerializer);template.setHashValueSerializer(jsonRedisSerializer);// 返回return template;}
}然后我们修改RedisDemoApplicationTests.java添加泛型 再跑一下测试类发现报错需要添加依赖 修改pom.xml添加依赖 !-- jackson --dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactId/dependency再重新运行测试类
这里采用了JSON序列化来代替默认的JDK序列化方式。最终结果如图 那实体类能否写入呢下面我们测试一下。 创建实体类com/heima/redis/pojo/User.java
Data
AllArgsConstructor
NoArgsConstructor
public class User {private Integer id;private String name;private Integer age;
}在测试类RedisDemoApplicationTests.java中添加方法 Testpublic void testSave(){// 写入数据redisTemplate.opsForValue().set(user:100,new User(1001,胡歌,46));// 获取数据Object o redisTemplate.opsForValue().get(user:100);User user (User) o;System.out.println(user);}看一下图形化界面
整体可读性有了很大提升并且能将Java对象自动的序列化为JSON字符串并且查询时能自动把JSON反序列化为Java对象。不过其中记录了序列化时对应的class名称目的是为了查询时实现自动反序列化。这会带来额外的内存开销。
3.5.StringRedisTemplate
为了节省内存空间我们可以不使用JSON序列化器来处理value而是统一使用String序列化器要求只能存储String类型的key和value。当需要存储Java对象时手动完成对象的序列化和反序列化。
因为存入和读取时的序列化及反序列化都是我们自己实现的SpringDataRedis就不会将class信息写入Redis了。
这种用法比较普遍因此SpringDataRedis就提供了RedisTemplate的子类StringRedisTemplate它的key和value的序列化方式默认就是String方式。 省去了我们自定义RedisTemplate的序列化方式的步骤而是直接使用
处理String类型
新建测试类RedisDemoStringTests.java
SpringBootTest
class RedisDemoStringTests {Autowired(required false)private StringRedisTemplate stringRedisTemplate;Testvoid testString() {stringRedisTemplate.opsForValue().set(tomato,blue);Object tomato stringRedisTemplate.opsForValue().get(tomato);System.out.println(tomato: tomato);}
}运行测试类 查看图形界面
处理实体类类型
那对象的话怎么办呢我们修改测试类RedisDemoStringTests.java
SpringBootTest
class RedisDemoStringTests {Autowired(required false)private StringRedisTemplate stringRedisTemplate;// 手动序列化工具private static final ObjectMapper mapper new ObjectMapper();Testpublic void testSave() throws JsonProcessingException {// 写入数据User user new User(1002, 张靓颖, 34);// 手动序列化String json mapper.writeValueAsString(user);stringRedisTemplate.opsForValue().set(user:200, json);// 获取数据String result stringRedisTemplate.opsForValue().get(user:200);System.out.println(result: result);}
}图形化界面如下
处理Hash类型
那如果是Hash类型呢 RedisDemoStringTests.java
SpringBootTest
class RedisDemoStringTests {Autowired(required false)private StringRedisTemplate stringRedisTemplate;Testpublic void testHash(){stringRedisTemplate.opsForHash().put(user:300,name,凤凰传奇);stringRedisTemplate.opsForHash().put(user:300,age,32);Object name stringRedisTemplate.opsForHash().get(user:300, name);System.out.println(name: name);Object age stringRedisTemplate.opsForHash().get(user:300, age);System.out.println(age: age);MapObject, Object entries stringRedisTemplate.opsForHash().entries(user:300);System.out.println(entries:entries);}
}输出结果 图形化界面如下
总结