黑马程序员Redis学习【持续更新】

Redis基础

一、Redis入门

1.Redis简介

【1】为什么学习Redis

100

Redis是一个基于内存的key-value结构数据库。「Remote Dictionary Service」的首字母缩写,也就是「远程字典服务-remote dictionary server」。

  • 基于内存存储,读写性能高
  • 适合存储热点数据(热点商品、资讯、新闻)
  • 企业营业广泛

【2】Redis介绍

Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库、缓存等。

官网:https://redis.io

中文网 https://www.redis.net.cn/

Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供的数据是可以达到10万+的QPS(Queries-per-second 每秒内查询次数)。它存储的value类型比较丰富,也被称为结构化的NoSql数据库。

NoSql(Not Only SQL),不仅仅是SQL,泛指非关系型数据库(数据之间没有关系)。

NoSql数据库并不是要取代关系型数据库,而是关系型数据库的补充。

关系型数据库(RDBMS):

  • Mysql
  • Oracle
  • DB2

非关系型数据库(NoSql):

  • Redis
  • Mongo DB
  • MemCached

2.使用Redis能做什么?

  • 数据缓存
  • 消息队列

101

3.Redis下载与安装

3.1Redis下载

Redis安装包分为windows和linux版本

  • Windows版下载地址:https://github.com/microsoftarchive/redis/releases
  • Linux版下载地址: https://download.redis.io/releases/

说明:

Redis官网只提供了linux版本,没有windows版本。windows版本由微软公司开发,不稳定,实际开发中我们一般都是使用linux版本。

3.2 Redis安装
1)在Linux中安装Redis
  • 安装过程介绍:

1.安装编译环境并且编译

2.安装redis

3.设置成后台运行

4.打开防火墙6379端口号

5.设置IP地址的bind

  • redis安装

1.先查看下是否安装了gcc-c++

redis是C语言开发,安装redis需要先将官网下载的源码进行编译,编译依赖gcc环境。如果没有gcc环境,需要安装gcc。

rpm -q gcc-c++

102

如果出现如上所示说明已经安装了。如果没有安装则执行下面命令进行安装即可。

yum -y install gcc-c++

2.上传"redis"到Linux系统/soft目录下

3.进入soft目录,将"redis-4.0.0.tar.gz"解压到当前目录

cd /usr/local/soft 
tar -zxvf redis-4.0.0.tar.gz

104

解压好之后会出现redis-4.0.0目录

切换到redis-4.0.0目录下查看内容,下面内容是redis的源码。

106

4.进入redis-4.0.0目录,使用make命令对上述源码在c语言的环境下进行编译redis 。make会调用gcc-c++编译redis源码,只有编译之后才可以进行安装。

make

107

如下信息代表编译成功

108

5.在redis-4.0.0目录中,使用以下命令,将redis安装到/usr/local/soft/redis指定的目录下

make PREFIX=/usr/local/soft/redis install 

109

​ 安装成功后在/usr/local/redis/bin目录下可以看到如下结构。

110

6.复制redis.conf配置文件到/usr/local/soft/redis/bin

111

112

113

安装后重点文件说明:

/usr/local/soft/redis/bin/redis-server:Redis服务启动脚本

/usr/local/soft/redis/bin/redis-cli:Redis客户端脚本

/usr/local/soft/redis/bin/redis.conf:Redis配置文件

2)在Windows中安装Redis

Redis的Windows版属于绿色软件,直接解压即可使用,解压后目录结构如下:

114

4.Redis服务启动与停止

1)Linux系统中启动和停止Redis 掌握
  • redis启动服务器

【1】前端模式启动(不使用这种模式)

直接运行bin/redis-server以前端模式启动,前端模式启动的缺点是启动完成后,不能再进行其他操作,如果要操作必须使用ctrl+c,同时redis-server程序结束,不推荐使用此方法。

./redis-server

115

使用CTRL+ C 停止前端模式

【2】后端模式启动(推荐使用)

1.修改redis.conf配置文件,修改daemonize yes 以后端模式启动。

daemonize:后台运行

vim redis.conf

116

保存并退出。

2.启动时,指定配置文件

cd /usr/local/soft/redis/bin./redis-server redis.conf

3.查看启动的后台进程

ps -aux | grep redis

117

redis启动客户端
  1. 进入redis/bin目录,启动"redis-cli"
./redis-cli

118

停止redis

在客户端向Redis发送shutdown命令

方法:在Redis客户端里面输入shutdown

119

注意:上述已经将redis服务关闭了,如果希望演示下面的远程访问redis必须先启动redis服务。

./redis-server redis.conf

120

2)Windows系统中启动和停止Redis 了解

Windows系统中启动Redis,直接双击redis-server.exe即可启动Redis服务,redis服务默认端口号为6379

121

如果双击无法启动redis,那么就打开dos窗口输入如下命令启动:

122

Ctrl + C停止Redis服务

双击redis-cli.exe即可启动Redis客户端,默认连接的是本地的Redis服务,而且不需要认证即可连接成功。

123

退出客户端可以输入exit或者quit命令。

5.使用可视化工具连接redis服务器端

通过上述演示我们发现通过命令行可以连接redis数据库服务器,但是在命令行中操作redis稍微麻烦一些。我们平时可以使用可视化工具操作redis服务器。

124

125

126

127

128

2.安装好之后的界面:

129

3.打开可视化工具,创建链接:

130

4.打开防火墙

我们发现使用可视化工具连接linux的redis服务器,会报错

131

如需远程连接redis,需配置redis端口6379在Linux防火墙中开放

#开放的端口永久保存到防火墙
firewall-cmd --zone=public --add-port=6379/tcp --permanent#重启防火墙
systemctl restart firewalld

132

使用windows下的客户端软件连接,发现客户端依然无法连接redis,这是由于redis本身安全机制的限制,默认只允许本机访问

133

5.修改配置允许其它机器访问

(1)默认redis只允许本机访问,如果想要其它机器访问,需要编辑redis.conf配置内容如下,添加当前Linux局域网的IP地址。

bind 127.0.0.1 192.168.18.128
或者直接插入:
bind 0.0.0.0  
# 使用0.0.0.0表示使用本地localhost 127  192.168.200.129都可以访问

说明:上述是绑定本地回环ip地址和外网访问的虚拟机ip地址的映射关系。

134

135

说明:输入完bind之后按回车,然后按字母n查找bind.到文件末尾输入o换行插入。一定要把注释符号#删除。

136

插入内容:

bind 0.0.0.0 

137

注意:一定将下图中的注释掉否则使用客户端不会连接上redis服务器端

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

保存退出。

(2)关闭redis,再重新启动Redis读取新的配置文件,才会起作用

./redis-cli shutdown
./redis-server redis.conf

139

(3)在Windows下使用Redis客户端访问Linux服务器上的Redis服务器

140

创建好连接之后就会看到redis默认的数据库:

redis默认含有16个数据库。默认使用第一个数据库。我们可以在连接192.168.200.128_linux_heima138上右键进行命令行操作redis数据库。

141

6.在其他数据库上存储数据

我们发现默认使用第一个数据库,我们可以使用select命令进行切换数据库,语法:

select 数据库索引 

142

说明:一个Redis服务器可以包括多个数据库,客户端可以只连接Redis中某个数据库,就好比一个mysql服务器中创建多个数据库,客户端连接时指定连接到哪个数据库。
Redis中有db0-db15编号的16个数据库。我们不能创建新的数据库,也不能删除数据库。数据库中也没有表的结构,客户端默认连接第0个数据库。

二、Redis的数据类型

1.数据类型介绍

1.1Redis的5种数据类型

redis是一种高级的key-value的存储系统,键是String类型,其中value支持五种数据类型,对于键和值的描述如下所示:

键(key):

​ 【1】键不能重复

​ 【2】作用:标识存储的数据

​ 【3】数据类型:String

​ 【4】命名规则:

​ 1)不能太长:因为查询的效率低,查询起来不方便

​ 2)不能太短:容易重复,同时可读性也差

​ 3)按照规范:HEIMA_STU_LIST

**值(value):**支持5种数据类型

值的数据类型值的格式说明
string字符串类型,类似于Java中String
hash由键值对组成,类似于Java中Map
list列表类型,类似于Java中List,元素是存取有序可以重复
set集合类型,类似于Java中Set,元素是存取无序,不可重复
sorted set/zset有序的集合类型,每个元素有一个分数用来决定它的顺序

143

2.string类型的操作命令

字符串类型是Redis中最为基础的数据存储类型,它在Redis中以二进制保存。无论存入的是字符串、整数、浮点类型都会以字符串写入。

在Redis中字符串类型的值最多可以容纳的数据长度是512M,这是以后最常用的数据类型

144

  • 常用命令

更多命令可以参考Redis中文网:https://www.redis.net.cn

命令功能
set 键 值添加或修改一个键和值,键不存在就是添加存在就是修改
get 键获取值,如果存在就返回值,不存在返回nil(就是C语言中NULL)
del 键删除指定的键和值,返回删除的个数
setex key seconds value设置指定key的值,并将key的过期时间设为seconds秒。此处的value是指key对应的value值。等价于: set key value ex seconds
expire key seconds如果一个key已经存在,要设置一个过期时间
setnx key value /set key value nx保存键值对,如果key存在则不保存,不存在则保存
补充:
批量操作:
mset name lisi addr xian
mget name addr
del name addr 
  • 命令演示
  1. 添加一个键为name,值为zhangsan
  2. 再设置一个键为age,值为13
  3. 得到name和age的值
  4. 删除name
  5. 批量添加name lisi addr sh
  6. 批量获取name age addr的值
  7. 批量删除name age
  8. 修改addr的值为bj
  9. 设置name2值为lisi,且存活5s,5秒后,内存销毁
  10. 也可通过set实现过期机制,ex 10表示存活10秒,例如设置name3值为zhaoliu,且存活5s,5秒后,内存销毁
  11. 使用set命令添加name4并赋值为wangwu,然后使用EXPIRE 设置过期时间。
  12. 如果键存在则不保存,不存在则保存。
  • 执行效果

145

9.设置name2值为lisi,且存活5s,5秒后,内存销毁

146

10.也可通过set实现过期机制,ex 10表示存活10秒,例如设置name3值为zhaoliu,且存活5s,5秒后,内存销毁

147

11.使用set命令添加name4并赋值为wangwu,然后使用EXPIRE 设置过期时间。

148

12.如果键存在则不保存,不存在则保存。

149

使用场景举例:

  • 用户登录后端保存短信验证码,并设置失效时间;
  • 代替后端session功能,实现分布式缓存(是将数据分散存储在多台独立的设备上)等;

小结

  1. 添加值: set 键 值
  2. 获取值:get 键
  3. 删除值:del 键

3.hash类型的操作命令

Redis中的Hash类型可以看成是键和值都是String类型的Map容器,每一个Hash可以存储4G个键值对。

150

​ 该类型非常适合于存储对象的信息。如一个用户有姓名、密码、年龄等信息,则可以有username、password和age等键,它的存储结构如下:

151

  • 常用命令
命令功能
hset 键 字段 值添加键、字段、值
hget 键 字段通过键、字段得到值
hmset 键 字段 值 字段 值multiply多个,一次添加多个字段和值
hmget 键 字段 字段通过键,获取多个字段和值
hdel 键 字段 字段删除一个或多个字段的值
hgetall 键得到这个键下所有的字段和值
HKEYS 键获取哈希表中所有字段
HVALS 键获取哈希表中所有值

命令演示:

  1. 创建hash类型的键为person,并且添加一个字段为name,值为zhangsan
  2. 向person中添加字段为age,值为13
  3. 向person中批量添加字段为addr,值为sh;字段为company,值为heima
  4. 分别得到person中的name、age的字段值
  5. 批量得到person中的name、age和addr的字段值
  6. 获取person中所有的字段以及对应的值
  7. 删除person中的name
  8. 批量删除person中的age、addr以及company

152

153

Hash数据结构的应用场景:

  • 购物车

以用户id为key,商品id为field,商品数量为value,恰好构成了购物车的3个要素,如下图所示

154

4.list类型的操作命令

​ 在Redis中,List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样。我们可以在其左部(left)和右部(right)添加新的元素。在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。List中可以包含的最大元素数量是4G。

155

常用命令

命令功能
lpush 键 元素 元素…left从左边向指定的键中添加1个或多个元素,返回列表中元素的个数
rpush 键 元素 元素…right从右边向指定的键中添加1个或多个元素
lpop 键从左边删除一个元素,返回被删除的元素
rpop 键从右边删除一个元素,返回被删除的元素
lrange 键 开始 结束得到键中指定范围的元素的数据
每个元素都有一个索引号,从左向右0~n
从右向左索引号:-1~-(n+1),每个元素有2个索引号
如果要取出整个列表中所有的元素,索引号应该是:0~-1
lindex 键 索引值查询指定索引的元素
llen 键获取列表的长度
brpop key1 [key2] timeout移出并获取列表的最后一个元素,如果列表没有元素会阻塞列表直接到等待超时或发现可弹出元素为止,超时时间单位默认是秒
lrem key 删除元素个数 value值从表头删除指定个数的元素
  • 命令演示

156

  1. 向mylist键的列表中,从左边添加a b c三个元素
  2. 从右边添加one two three三个元素
  3. 查询索引0到2的数据
  4. 查询所有的元素
  5. 查询索引是2的数据
  6. 从右边添加一个重复的元素three
  7. 删除最左边的元素c
  8. 删除最右边的元素three
  9. 获取列表中元素的个数
  10. 向列表list1中添加数据,并移除列表中最后一个元素,如果列表中没有该元素则等待指定时间
  11. 向列表list1中添加元素: a b c b b. 然后删除2个b元素
  • 执行效果

157

10.向列表list1中添加数据,并移除列表中最后一个元素,如果列表中没有该元素则等待指定时间

158

11.向列表list1中添加元素: a b c b b. 然后删除2个b元素。

159

使用场景:

  • 微信朋友圈点赞,要求按照点赞顺序显示点赞好友信息。如果取消点赞,移除对应好友信息。
  • list类型的lrange命令可以分页查看队列中的数据。可将每隔一段时间计算一次的排行榜存储在list类型中,如京东每日的手机销量排行、学校每次月考学生的成绩排名等,下图是酷狗音乐“K歌擂台赛”的昨日打擂金曲排行榜,每日计算一次,存储在list类型中。

5.set类型的操作命令

​ 在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加、删除或判断某一元素是否存在等操作。Set可包含的最大元素数量是4G,和List类型不同的是,Set集合中不允许出现重复的元素。

160

161

  • 常用命令
命令功能
sadd 键 元素 元素…向一个键中添加1个或多个元素
smembers 键得到这个集合中所有的元素
sismembebr 键 元素判断指定的元素在集合中是否存在,存在返回1,不存在返回0
srem 键 元素 元素…通过键删除一个或多个元素
sinter key1 [key2]返回给定所有集合的交集(集合中都共有的部分)
  • 命令演示
  1. 向myset集合中添加A B C 1 2 3 六个元素
  2. 再向myset中添加B元素,看能否添加成功
  3. 显示所有的成员,发现与添加的元素顺序不同,元素是无序的
  4. 删除其中的C这个元素,再查看结果

162

5.判断A是否在myset集合中

6.判断D是否在myset集合中

163

7.向两个集合中添加数据,查看两个集合的交集

164

应用场景:

  • 需要去重的少量信息,比如:身份证信息、手机号码等作为黑名单|白名单;

  • 共同好友查询,使用set的交集;

    • eg: zhang:{11,22,33,44} lisi:{22,33,66,88}

      ​ zhangsan和lisi共同的好友:交集取22 33即可.

6.zset/sorted set类型的操作命令

Redis 有序集合(sorted set)和set集合一样也是无序不可以重复。不同的是每个元素都会关联一个分数(排序因子)。

redis正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复,每个集合可存储40多亿个成员。

165

166

  • 命令
命令功能
zadd 键 分数 值 分数 值添加1个或多个元素,每个元素都有一个分数
zrange 键 开始索引 结束索引获取指定范围的元素,得到所有的元素,索引是0到-1
zrange 键 开始索引 结束索引 withscores查询指定的元素和对应的分数
zrevrange 键 开始索引 结束索引 withscores按照分数倒叙获取指定元素和对应的分数
zrem 键 值 值…删除一个或多个值
zcard 键得到元素个数
zrank 键 值得到元素的索引号
zscore 键 值得到元素的分数
  • 操作
  1. 添加键country,分数是10,值是Japan
  2. 添加键country,分数是5,值是USA,添加键country,分数是50,值是Russia
  3. 添加键country,分数是1,值是China,分数是120,值是Korea
  4. 查询country中所有的元素

167

​ 5.查询所有的元素和对应的分数

​ 6.按照分数倒叙获取所有的元素和对应的分数

168

  1. 查询索引是0 到 1的值

169

  1. 查询Japan的索引号(从0开始)
  2. 删除值为USA的元素
  3. 查询country中还有多少个元素
  4. 显示Russia的分数值

170

应用场景:

1.b站视频点击量排名

2.新浪热点文章点击量、收藏量等排名

三、Redis的其他操作

1.Redis的通用命令

  • 常用命令
命令功能
keys 匹配字符查询所有的键,可以使用通配符
* 匹配多个字符
? 匹配一个字符
del 键1 键2删除任何的值类型,而且可以同时删除多个键
exists 键判断指定的键是否存在,不存在返回0 存在返回1
type 键判断指定的键,值的类型。返回是类型的名字
select 数据库编号选择其他的数据库
move 键 数据库编号将当前数据库中指定的键移动到另一个数据库中
TTL key返回给定key的剩余生存时间(TTL,time to live),以秒为单位
从Redis2.8开始:如果key不存在或者已过期,返回-2;如果key存在并且没有设置过期时间(永久有效),返回-1
flushallredis的flushall命令用来清空redis所有的库,测试可以使用,开发中最好不要用。
  • 命令演示
  1. 添加字符串name的值为zhangsan, myset 的值为20
  2. 显示所有的键
  3. 显示所有以my开头的键
  4. 显示所有my后面有三个字符的键
  5. 添加一个字符串:name2 lisi
  6. 添加一个list:name3 a b c d

171

  1. 显示所有的键
  2. 一次删除name2和name3这两个键,其中name2和name3是不同的类型,显示所有键
  3. 分别判断name和name2是否存在

172

  1. 分别判断name user myset mylist分别是什么类型
  2. 切换数据库到15,向15中添加一个name2 wangwu,得到name2的值显示。
  3. 将15中的name2移到0中
  4. 切换到数据库0,显示所有的键

173

  1. 返回给定 key 的剩余生存时间(TTL, time to live),以秒为单位

174

四、在Java中操作redis

1.介绍

前面我们讲解了Redis的常用命令,这些命令是我们操作Redis的基础,那么我们在java程序中应该如何操作Redis呢?这就需要使用Redis的java客户端,就如同我们使用JDBC操作Mysql数据库一样。

Redis的java客户端很多,官方推荐的有三种:

  • Jedis
  • Lettuce
  • Redisson

Spring对Redis客户端进行了整合,提供了Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即spring-boot-starter-data-redis。

2. Jedis

2.1使用介绍

Jedis是Redis的java版本的客户端实现。

maven坐标:

<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.8.0</version>
</dependency>

使用Jedis操作Redis的步骤:

​ 1.获取连接

​ 2.执行操作

​ 3.关闭连接

2.2Jedis类常用方法

注:每个方法就是redis中的命令名,方法的参数就是命令的参数。

在每次访问Redis数据库的时候,都需要创建一个Jedis对象。每个Jedis对象似于JDBC中Connection对象,类似于mybatis中session对象。

连接和关闭功能
new Jedis(host, port)创建Jedis连接对象,参数: host: 服务器地址 port:端口号6379
void close()关闭连接
对Stirng操作的方法说明
set(String key , String value)添加字符串类型的键和值
String get(String key)通过键得到字符串的值
del(String … keys)删除一个或多个键
对hash操作的方法说明
hset(String key,String field,String value)添加一个hash类型的键,字段和值
Map<String ,String> hgetall(String key)通过一个键得到所有的字符和值,返回Map
对list操作的方法说明
lpush(String key,String…values)从左边添加多个值到list中
List<String> lrange(String key,long start,long end)通过键得到指定范围的元素
对set操作的方法说明
sadd(String key,String…values)添加一个或多个元素
Set<String> smembers(String key)通过键得到集合所有的元素
对zset操作的方法说明
zadd(String key, double score, String member)添加一个键,分数和值
Set<String> zrange(String key, long start, long end)查询一个指定范围的元素
2.3案例:Jedis的基本操作

操作步骤:

1.导入依赖

<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.8.0</version>
</dependency>

2.创建测试类,书写操作redis数据库的代码,代码一共分为三步:

  • 创建jedis对象,连接redis数据库服务器 new jedis(host,port)
  • 操作数据
  • 关闭连接

【1.下面是操作字符串数据的代码】:

package com.itheima.sh.jedis_test_01;import org.junit.Test;
import redis.clients.jedis.Jedis;import java.util.List;public class JedisTest01 {/*jedis入门*/@Testpublic void test01(){//1.创建jedis对象,连接redis数据库服务器 new Jedis(host,port)Jedis jedis = new Jedis("127.0.0.1",6379);//2.操作数据//【1】字符串jedis.set("username", "柳岩");//获取String username = jedis.get("username");System.out.println("username = " + username);//一次性添加多个数据 mset(key1,value1,key2,value2,...)jedis.mset("addr", "sh", "company", "黑马");//获取所有的数据List<String> values = jedis.mget("username", "addr", "company");System.out.println("values = " + values);//3.关闭连接jedis.close();}
}

控制台输出结果:

image-20200212172111495

小结:

1.一次性添加多个字符串数据,使用的方法如下:

mset(key1,value1,key2,value2,...)

2.一次性获取所有的字符串:

List<String> mget(key1,key2,key3...);

【2.下面是操作hash数据的代码】:

package com.itheima.sh.jedis_test_01;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JedisTest01 {/*jedis入门*/@Testpublic void test01(){//1.创建jedis对象,连接redis数据库服务器 new Jedis(host,port)Jedis jedis = new Jedis("127.0.0.1",6379);//2.操作数据//【2】hashjedis.hset("person", "username", "锁哥");//存储多个数据 注意这里map集合的键和值都是String类型Map<String, String> map = new HashMap<>();map.put("age", "18");map.put("height", "180");jedis.hmset("person", map);//获取hash中的所有的数据Map<String, String> map1 = jedis.hgetAll("person");System.out.println(map1);//3.关闭连接jedis.close();}
}

控制台输出结果:

image-20200212173846415

小结:

1.向hash中添加一个数据:

jedis.hset(key, field, value);

2.向hash中添加多个数据:

jedis.hset(key, map集合);

3.获取hash中所有的数据:

Map<String, String> map1 = jedis.hgetAll(key);

3.Spring Data Redis

3.1介绍

Spring Data Redis是Spring的一部分,提供了在Spring应用中通过简单的配置就可以访问Redis服务,对Redis底层开发包进行了高度封装。在Spring项目中,可以使用Spring Data Redis来简化Redis操作。

网址:https://spring.io/projects/spring-data-redis

image-20210927143741458

maven坐标:

<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>2.4.8</version>
</dependency>

SpringBoot提供了对应的Starter,maven坐标:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

SpringDataRedis中提供了一个高度封装的类:RedisTemplate,针对类似Jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:

  • ValueOperations:简单K-V操作(String类型)
  • SetOperations:set类型数据操作
  • ZSetOperations:zset类型数据操作
  • HashOperations:针对hash类型的数据操作
  • ListOperations:针对list类型的数据操作
3.2使用方式
3.2.1环境搭建

直接导入素材中的代码到idea中即可:

image-20221212230526534

image-20221212230618218

第一步:创建maven项目springdataredis_demo,配置pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.5</version><relativePath/></parent><groupId>com.itheima</groupId><artifactId>springdataredis_demo</artifactId><version>1.0-SNAPSHOT</version><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.5</version></plugin></plugins></build>
</project>

第二步:编写启动类

package com.itheima;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class App {public static void main(String[] args) {SpringApplication.run(App.class,args);}}

第三步:配置application.yml

spring:#Redis相关配置redis:host: 192.168.200.128 # 连接linux系统的redisport: 6379 # 端口号database: 0 #操作的是0号数据库

解释说明:

spring.redis.database:指定使用Redis的哪个数据库,Redis服务启动后默认有16个数据库,编号分别是从0到15。

可以通过修改Redis配置文件来指定数据库的数量。

第四步:提供测试类

package com.itheima.test;import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@SpringBootTest
public class SpringDataRedisTest {@Autowiredprivate RedisTemplate redisTemplate;}
3.2.2操作字符串类型数据

image-20221227121633760

需求:

1.存入数据和取出数据

2.存值并设置过期时间

3.如果存在值则不执行任何操作

  /*** 操作String类型的数据*/@Testpublic void test01String(){//获取操作String类型的接口对象ValueOperations valueOperations = redisTemplate.opsForValue();//存值valueOperations.set("city123","beijing");//取值String value = (String) valueOperations.get("city123");System.out.println(value);//存值,同时设置过期时间   TimeUnit:超时时间单位/*void set(K key, V value, long timeout, TimeUnit unit);key :字段keyvalue:key对应的值timeout:超时时间TimeUnit:超时时间单位*/valueOperations.set("username","suoge",10, TimeUnit.SECONDS);//存值,如果存在则不执行任何操作Boolean aBoolean = valueOperations.setIfAbsent("city1234", "nanjing");System.out.println(aBoolean);}

上述操作完毕之后,在客户端查看键,如下所示:

image-20221212223739407

因为默认的key序列化器为JdkSerializationRedisSerializer,导致我们存到Redis中后台的数据可原始数据有差别。如果我们想要存储的key是正常的key,我们可以使用如下配置类,当前配置类不是必须的,因为SpringBoot框架会自动装配RedisTemplate对象。

配置类:

package com.itheima.config;import org.springframework.cache.annotation.CachingConfigurerSupport;
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.StringRedisSerializer;/*** Redis配置类*/
@Configuration
public class RedisConfig extends CachingConfigurerSupport {/*1.RedisConnectionFactory 是获取RedisConnection对象的,RedisConnection相当于jdbc中的连接对象Connection表示和Redis进行连接*/@Beanpublic RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {//创建Redis模板对象RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();//默认的Key序列化器为:JdkSerializationRedisSerializer//StringRedisSerializer支持字符串类型的转化,而且默认使用UTF-8编码//下面代码的意思是使用StringRedisSerializer序列化器替换默认的Key序列化器JdkSerializationRedisSerializerredisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setConnectionFactory(connectionFactory);return redisTemplate;}}
3.2.3操作哈希类型数据

image-20221227121212541

需求:

1.存储几个哈希类型的数据

2.获取哈希类型的数据

3.根据键获取哈希类型中的所有字段

4.获得hash结构中的所有值

/*** 操作Hash类型数据
*/
@Test
public void testHash(){//获取操作Hash类型的接口对象HashOperations hashOperations = redisTemplate.opsForHash();//存值 下面的代码相当于命令:hset person name xiaoming//pseron表示键,name表示字段名  xiaoming表示字段值hashOperations.put("person","name","xiaoming");hashOperations.put("person","age","20");hashOperations.put("person","address","bj");//取值//下面的代码相当于执行命令:hget 键 字段===》hget person age===>表示根据键和字段名获取字段值String age = (String) hashOperations.get("person", "age");System.out.println(age);//获得hash结构中的所有字段//下面的代码相当于执行命令:HKEYS 键===》HKEYS personSet keys = hashOperations.keys("person");for (Object key : keys) {System.out.println(key);}//获得hash结构中的所有值//HVALS 键List values = hashOperations.values("person");for (Object value : values) {System.out.println(value);}
}
3.2.4操作列表类型数据

image-20221227120859682

需求:

1.向列表中添加数据

2.查询列表中所有数据

/*** 操作List类型的数据
*/
@Test
public void testList(){//获取操作列表类型的接口对象ListOperations listOperations = redisTemplate.opsForList();//存值//命令lpush 键 元素 元素...listOperations.leftPush("mylist","a");listOperations.leftPushAll("mylist","b","c","d");//取值//命令:lrange 键 开始 结束//下面的代码是查询所有List<String> mylist = listOperations.range("mylist", 0, -1);for (String value : mylist) {System.out.println(value);}//获得列表长度 命令:llen 键Long size = listOperations.size("mylist");for (int i = 0; i < size; i++) {//出队列//命令:rpop 键//从右边删除一个元素,返回被删除的元素String element = (String) listOperations.rightPop("mylist");System.out.println(element);}
}
3.2.5 操作set集合类型数据

image-20221227120830991

需求:

1.向set集合中添加数据

2.获取指定set集合的所有的元素

3.删除指定set集合的数据

/*** 操作Set类型的数据
*/
@Test
public void testSet(){//获取操作set类型的接口对象SetOperations setOperations = redisTemplate.opsForSet();//存值//sadd 键 元素 元素...setOperations.add("myset","a","b","c","a");//取值//smembers 键 : 得到这个集合中所有的元素Set<String> myset = setOperations.members("myset");for (String o : myset) {System.out.println(o);}//删除成员//srem 键 元素 元素...setOperations.remove("myset","a","b");//取值myset = setOperations.members("myset");for (String o : myset) {System.out.println(o);}}
3.2.6操作有序集合类型数据

image-20221227123907367

需求:

1.向zset中添加数据

2.从zset中取出数据

3.对某个值的分数进行加20

4.删除数据

/*** 操作ZSet类型的数据
*/
@Test
public void testZset(){//获取操作zSet类型的接口对象ZSetOperations zSetOperations = redisTemplate.opsForZSet();//存值//Boolean add(K var1, V var2, double var3)  var1 表示键  var2 表示值   var3表示分数zSetOperations.add("myZset","a",10.0);//myZset 表示键  a 表示值   10.0 表示分数zSetOperations.add("myZset","b",11.0);zSetOperations.add("myZset","c",12.0);zSetOperations.add("myZset","a",13.0);//取值//命令:zrange 键 开始索引 结束索引//获取指定范围的元素,得到所有的元素,索引是0到-1Set<String> myZset = zSetOperations.range("myZset", 0, -1);for (String s : myZset) {System.out.println(s);}//修改分数//下面的方法表示在原来分数上进行加20zSetOperations.incrementScore("myZset","c",20.0);//删除成员zSetOperations.remove("myZset","a","b");//取值Set<ZSetOperations.TypedTuple> myZset = zSetOperations.rangeWithScores("myZset", 0, -1);for (ZSetOperations.TypedTuple typedTuple : myZset) {Double score = typedTuple.getScore();Object value = typedTuple.getValue();System.out.println(score+"---"+value);}
}
3.2.7通用操作

image-20221227130603735

需求:

1.获取Redis中所有的key

2.判断某个key是否存在

3.删除指定key

4.获取指定key对应的value的数据类型

/*** 通用操作,针对不同的数据类型都可以操作
*/
@Test
public void testCommon(){//获取Redis中所有的keySet<String> keys = redisTemplate.keys("*");for (String key : keys) {System.out.println(key);}//判断某个key是否存在Boolean itcast = redisTemplate.hasKey("itcast");System.out.println(itcast);//删除指定keyredisTemplate.delete("myZset");//获取指定key对应的value的数据类型DataType dataType = redisTemplate.type("myset");System.out.println(dataType.name());}
3.2.8整合连接池

关于redis连接池并没有什么效果,配置好之后会优化获取连接性能。

pom引入依赖:

<!-- redis创建连接池,默认不会创建连接池 -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>

配置连接池:

# 配置redis环境
spring:redis:# 默认连接本地localhost,如果仅仅连接本地redis服务,则可不写host: 192.168.200.128# 默认端口是6379,则省略不写port: 6379# redis实例中分为16分片库,索引位从0~15,默认操纵的是0database: 0lettuce:pool:max-active: 8 # 连接池最大连接数(使用负值表示没有限制)max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)max-idle: 8 # 连接池中的最大空闲连接min-idle: 1  # 连接池中的最小空闲连接

五、Redis持久化机制

1.Redis持久化

问题:把服务端关闭了,再重新开启服务器,数据会不会丢失?

答:会部分丢失,因为默认redis服务器每隔一段时间写入一次内存中数据到硬盘上。

Redis持久化概述:

Redis是一个内存存储的数据库,内存必须在通电的情况下才能够对数据进行存储。如果,在使用redis的过程中突然发生断电,数据就会丢失。为了防止数据丢失,redis提供了数据持久化的支持。

持久化:把内存中的数据保存到硬盘上。
作用:防止数据在断电的情况下丢失。

image-20200211102120888

redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到磁盘来保证持久化。redis支持两种持久化方式,一种是RDB(快照)也是默认方式,另一种是Append Only File(缩写AOF)的方式。下面分别介绍:

注意:redis将内存中数据,写在硬盘文件上。服务器关闭,电脑重启数据也不会丢失。

Redis持久化的两种方式:

  • RDB:Redis DataBase 默认的持久化方式,以二进制的方式将数据写入文件中。每隔一段时间写入一次。
  • AOF:Append Only File 以文本文件的方式记录用户的每次操作,数据还原的时候,读取AOF文件,模拟用户的操作,将数据还原。

2.RDB持久化介绍

RDB是默认的持久化方式。这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为:dump.rdb。

补充:快照:当前内存中数据的状态

image-20200211105359322

可以通过配置设置自动做快照持久化的方式。如下面配置的是RDB方式数据持久化时机,必须两个条件都满足的情况下才进行持久化的操作:

关键字时间(秒)修改键数解释
save9001到了15分钟修改了1个键,则发起快照保存
save30010到了5分钟修改了10个键,则发起快照保存
save6010000到了1分钟,修改了1万个键,则发起快照保存

image-20221214154802305

缺点:可能导致数据丢失。因为RDB是每隔一段时间写入数据,所以系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
优点:持久化效率高,持久化的是内存中的数据数据库宕机后,数据恢复的效率要更高;

3、AOF的存储方式

由于快照方式是在一定间隔时间做一次的,所以如果redis宕机,就会丢失最后一次快照后的所有修改。如果应用要求不能丢失任何修改的话,可以采用AOF持久化方式。

​ AOF指的是Append only file,使用AOF持久化方式时,redis会将每一个收到的写命令都通过write函数追加到文件中(默认是appendonly.aof).当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。

image-20200211210914131

image-20200211210933936

AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。也可以通过该文件完成数据的重建。该机制可以带来更高的数据安全性,所有的操作都是异步完成的。

Redis中提供了3种同步策略说明
每秒同步每过一秒记录一次
每修改同步每次修改(增删改)都会记录一次
不同步由系统记录操作
  • AOF持久化机制配置
    • 开启AOF持久化

AOF默认是关闭的,首先需要开启AOF模式

参数配置说明
appendonly no/yes默认是no,关闭。如果要打开,设置成yes。

AOF持久化时机

关键字持久化时机解释
appendfsynceverysec每秒记录
appendfsyncalways每修改记录
appendfsyncno完全依赖操作系统,性能最好,持久化无法保证

everysec:每秒钟写入磁盘一次,在性能和持久化方面做了很好的折中。

always:收到写命令就立即写入磁盘,最慢,但是保证完全的持久化。

no:完全依赖操作系统,性能最好,持久化无法保证。

3.1演示:AOF持久化

1.打开AOF的配置文件redis.conf,设置appendonly yes

image-20221214160007849

image-20221214160122312

image-20200211234423632

2.通过./redis-server redis.conf启动服务器,在服务器目录下出现appendonly.aof文件。大小是0个字节。

image-20221214160331457

image-20221214160517810

3.添加3个键和值

1553423644984

4.打开appendonly.aof文件,查看文件的变化。会发现文件记录了所有操作的过程。

image-20221214160700964

image-20200211234841553

说明:

1.*2表示有两个命令  select 0 选择第一个数据库
2.$6表示select 有六个字符 1 表示0有一个字符

4.Redis持久化机制RDB和AOF的区别

1.RDB持久化机制优点和缺点

优点
  1. 方便备份与恢复

  2. 启动效率更高

相比于AOF机制,如果数据集很大,RDB的启动效率会更高。因为RDB文件中存储的是数据,启动的时候直接加载数据即可,而AOF是将操作数据库的命令存放到AOF文件中,然后启动redis数据库服务器的时候会将很多个命令执行加载数据。如果数据量特别大的时候,那么RDB由于直接加载数据启动效率会比AOF执行命令加载数据更高。

  1. 性能最大化

​ 对于Redis的服务进程而言,在开始持久化时,会在后台开辟子线程,由子线程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。

缺点
  1. 不能完全避免数据丢失

因为RDB是每隔一段时间写入数据,所以系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。

  1. 会导致服务器暂停的现象

由于RDB是通过子线程来协助完成数据持久化工作的,因此当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。

就是数据量过大,会开辟过多的子线程进行持久化操作,那么会占用服务器端的大量资源,那么有可能会造成服务器端卡顿。同时会造成服务器停止几百毫秒甚至一秒。

2.AOF持久化机制优点和缺点

优点

AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。也可以通过该文件完成数据的重建。该机制可以带来更高的数据安全性,所有的操作都是异步完成的。

缺点
  1. 运行效率比RDB更慢:根据同步策略的不同,AOF在运行效率上往往会慢于RDB。

  2. 文件比RDB更大:对于相同数量的数据集而言,AOF文件通常要大于RDB文件。

一般在企业开发中两种持久化机制会配合着使用。
持久化无法保证 |

everysec:每秒钟写入磁盘一次,在性能和持久化方面做了很好的折中。

always:收到写命令就立即写入磁盘,最慢,但是保证完全的持久化。

no:完全依赖操作系统,性能最好,持久化无法保证。

3.1演示:AOF持久化

1.打开AOF的配置文件redis.conf,设置appendonly yes

[外链图片转存中…(img-fFhLN1h2-1731121456337)]

[外链图片转存中…(img-1WwFS5Ju-1731121456338)]

[外链图片转存中…(img-Z6qtgO5S-1731121456338)]

2.通过./redis-server redis.conf启动服务器,在服务器目录下出现appendonly.aof文件。大小是0个字节。

[外链图片转存中…(img-vhHe693d-1731121456339)]

[外链图片转存中…(img-8FyvaFp3-1731121456339)]

3.添加3个键和值

[外链图片转存中…(img-7ry6nT1R-1731121456340)]

4.打开appendonly.aof文件,查看文件的变化。会发现文件记录了所有操作的过程。

[外链图片转存中…(img-HHESpOxM-1731121456340)]

[外链图片转存中…(img-mPLyQncf-1731121456341)]

说明:

1.*2表示有两个命令  select 0 选择第一个数据库
2.$6表示select 有六个字符 1 表示0有一个字符

4.Redis持久化机制RDB和AOF的区别

1.RDB持久化机制优点和缺点

优点
  1. 方便备份与恢复

  2. 启动效率更高

相比于AOF机制,如果数据集很大,RDB的启动效率会更高。因为RDB文件中存储的是数据,启动的时候直接加载数据即可,而AOF是将操作数据库的命令存放到AOF文件中,然后启动redis数据库服务器的时候会将很多个命令执行加载数据。如果数据量特别大的时候,那么RDB由于直接加载数据启动效率会比AOF执行命令加载数据更高。

  1. 性能最大化

​ 对于Redis的服务进程而言,在开始持久化时,会在后台开辟子线程,由子线程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。

缺点
  1. 不能完全避免数据丢失

因为RDB是每隔一段时间写入数据,所以系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。

  1. 会导致服务器暂停的现象

由于RDB是通过子线程来协助完成数据持久化工作的,因此当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。

就是数据量过大,会开辟过多的子线程进行持久化操作,那么会占用服务器端的大量资源,那么有可能会造成服务器端卡顿。同时会造成服务器停止几百毫秒甚至一秒。

2.AOF持久化机制优点和缺点

优点

AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。也可以通过该文件完成数据的重建。该机制可以带来更高的数据安全性,所有的操作都是异步完成的。

缺点
  1. 运行效率比RDB更慢:根据同步策略的不同,AOF在运行效率上往往会慢于RDB。

  2. 文件比RDB更大:对于相同数量的数据集而言,AOF文件通常要大于RDB文件。

一般在企业开发中两种持久化机制会配合着使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/10174.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

利用SEO在4个月内打造每月940美元的导航站

在软件开发领域&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;的潜力常常被人们低估&#xff0c;但它却能为网站增长带来显著效果。特别是在AI技术的加持下&#xff0c;你可以极大地加速流量增长并自动化大部分工作。本文将详细介绍一名Reddit用户如何在4个月内&#xf…

字节青训-数字字符串格式化

问题描述 小M在工作时遇到了一个问题&#xff0c;他需要将用户输入的不带千分位逗号的数字字符串转换为带千分位逗号的格式&#xff0c;并且保留小数部分。小M还发现&#xff0c;有时候输入的数字字符串前面会有无用的 0&#xff0c;这些也需要精简掉。请你帮助小M编写程序&…

HER304-ASEMI轴向高效恢复二极管HER304

编辑&#xff1a;ll HER304-ASEMI轴向高效恢复二极管HER304 型号&#xff1a;HER304 品牌&#xff1a;ASEMI 封装&#xff1a;DO-27 特性&#xff1a;轴向高效恢复二极管 正向电流&#xff1a;3A 反向耐压&#xff1a;300V 恢复时间&#xff1a;35ns 引脚数量&#xf…

信息宣传投稿栽跟头不可怕,关键是你要能再站起来

在繁忙的市郊,一家的事业基层单位,这里汇聚了各路英才,每个科室都有自己的专长。然而,有一项任务,让这些精英们头疼不已——单位信息宣传投稿。 起初,大家对这项任务并不以为然,以为不过是小菜一碟。李科长甚至开玩笑说:“不就是写篇文章,投个稿嘛,我们这些笔杆子还怕这个?”…

iMeta | 复杂热图(ComplexHeatmap)可视化文章最新版,画热图就引它

复杂热图可视化 https://doi.org/10.1002/imt2.43 PROTOCOL ●2022年8月&#xff0c;德国癌症研究中心顾祖光在iMeta在线发表了题为“Complex heatmap visualization”的方法类文章。 ● 该研究系统性地介绍了 ComplexHeatmap R包在复杂热图可视化方面的特性和功能。 ● 第…

HTTP的了解

从输入 URL 到页面展示到底发生了什么&#xff1f;&#xff08;非常重要&#xff09; 类似的问题&#xff1a;打开一个网页&#xff0c;整个过程会使用哪些协议&#xff1f; 先来看一张图&#xff08;来源于《图解 HTTP》&#xff09;&#xff1a; 上图有一个错误需要注意&…

博弈论(所有情况最优解)——课堂笔记

博弈论(所有情况最优解)——课堂笔记|【博弈论】分割数游戏-CSDN博客https://blog.csdn.net/back_room/article/details/143464453?spm=1001.2014.3001.5501【博弈论】拍卖土地-CSDN博客

网络编程——TCP通信练习

目录 一、多发多收 二、接收和反馈 三、上传文件 四、解决上传文件名重复问题 五、上传文件多线程版 六、上传文件线程池版 七、B/S(接收浏览器的消息并打印) 一、多发多收 客户端&#xff1a;多次发送数据 服务器&#xff1a;接收多次数据&#xff0c;并打印 public cl…

Selenium自动化测试 —— 模拟鼠标键盘的操作事件

软件测试资料领取&#xff1a;[内部资源] 想拿年薪40W的软件测试人员&#xff0c;这份资料必须领取~ 软件测试面试刷题工具&#xff1a;软件测试面试刷题【800道面试题答案免费刷】 鼠标操作事件 在实际的web产品测试中&#xff0c;对于鼠标的操作&#xff0c;不单单只有clic…

线性回归模型

线性回归模型 代价函数 梯度下降 学习率 梯度下降的收敛与调优 梯度下降的收敛性依赖于以下因素&#xff1a; 学习率的选择&#xff1a;合适的学习率能够确保稳定收敛&#xff0c;过大或过小的学习率可能会导致收敛不稳定或效率低下。数据的特征&#xff1a;数据的规模和特征…

书生大模型基础岛第一关书生大模型全链路开源体系

本文档相当于是对书生*浦语的了解文档 官网&#xff1a; https://internlm.intern-ai.org.cn/ github: https://github.com/internLM/ 开源之路&#xff1a; 2023.7.6 InterLM-7B2023.9.20 InterLM-20B2024.1.17 InternLM22024.7.4 InternLM2.5 性能天梯&#xff1a; InternL…

01OpenGL基本学习

文章目录 第一节1、概念立即模式vs核心模式 2、问题 第二节1、三维坐标系![三维坐标系](https://i-blog.csdnimg.cn/direct/0703ba6b68914b08b1d14b936ccd862d.png)2、什么是模型&#xff1f;3、什么是颜色&#xff1f;4、材质 第三节渲染管线第四节GLAD配置流程1、为什么需要G…

测试-请求特定资源使用Postman工具(3)

目录 前言 实操 开发者工具 前言 介绍过&#xff0c;就不再介绍了&#xff0c;只需要知道它是一个网络请求的工具就行了 实操 开发者工具 这里我们还需要借助开发者工具来帮助我们进行资源的请求&#xff0c;这里用 百度一下 进行测试 如下是 百度一下 的首页 右键打开…

Foliate:沉浸式阅读!!!

项目简介 Foliate 是一款开源的电子书阅读器&#xff0c;专为现代操作系统设计&#xff0c;提供了优雅且实用的阅读体验。它支持多种电子书格式&#xff0c;包括 EPUB、Mobipocket、Kindle、FB2、CBZ 和 PDF&#xff0c;让用户能够以分页或滚动模式阅读。Foliate 允许用户自定义…

打包18款AI营销神器,批量运营项目收藏必备!

淘金的不如卖铲子的&#xff0c;AI工具的应用越来越普及&#xff0c;这也让很多原本淘金的人都来卖铲子。如果自己能有很好的铲子&#xff0c;自己也会淘金&#xff0c;就可以既能卖铲子赚钱&#xff0c;也能掏金赚钱。 还有两天就是双十一了&#xff0c;各种AI工具&#xff0…

【MyBatis源码】SQL 语句构建器AbstractSQL

文章目录 介绍org.apache.ibatis.jdbc.SQLSQL类使用示例SelectProvider搭配动态SQLAbstractSQL类源码分析 介绍 当我们需要使用Statement对象执行SQL时&#xff0c;SQL语句会嵌入Java代码中。SQL语句比较复杂时&#xff0c;我们可能会在代码中对SQL语句进行拼接&#xff0c;查…

Vue2进阶

1.el安装 官网地址 Element - The worlds most popular Vue UI frameworkElement&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库https://element.eleme.cn/#/zh-CN 安装 npm install element-ui -S 引入组件&#xff08;在 main.js&#xf…

案例:三次锁定(下)

第二步: 在 Form1.cs 中完成以下代码 using Dome16_三次锁定.service; using Dome16_三次锁定.service.serviceimpl; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using Sys…

前端学习笔记—Vue3特性

一、 Vue3与Vite构建工具简介 image.png image.png image.png image.png Vite构建工具&#xff08;其他的打包工具有webpack&#xff0c;grunt&#xff0c;gulp&#xff09; image.png image.png 构建 二、创建Vue3项目 vite在TypeScript结合使用上&#xff0c;直接开箱即用&am…

iOS 去掉URL里面的百分号符号

遇到这个一段字符串 “publicId2030095197043302&publicBizTypeCONTENT_USER&chInfoch_life__chsub_Ndiscovery.featured&logoUrlhttps%3A%2F%2Fmdn.alipayobjects.com%2Fopen_content%2Fafts%2Fimg%2FA*_SUKQodfigcAAAAAAAAAAAAAfVx1AQ%2Foriginal&publicName…