43-Redis-heima-笔记
笔记内容来自黑马程序员视频教程
一、Redis入门
①:简介


②:应用场景
③:下载与安装
④:Redis服务启动与停止
01. Linux中redis服务启动
- Linux中edis服务启动,可以使用redis-server,默认端口号为6379
- Ctrl+C停止Redis服务
1.启动服务 执行redis-server在src目录下 进入src目录:cd /usr/oop/redis/redis-4.0.0/src 执行redis-server: ./redis-server |
---|
 |
2. 连接Redis 进入src目录:cd /usr/oop/redis/redis-4.0.0/src 执行redis-cli: ./redis-cli |
---|
 |
02 . Linux中后台运行redis服务
修改配置文件( redis.conf)
1. 进入到 /usr/oop/redis/redis-4.0.0 目录下
2. vim redis.conf
3. 将 daemonize no 修改为 daemonize yes


1. 保存退出后(重新启动服务) 进入目录:cd /usr/oop/redis/redis-4.0.0 执行redis-server并加载文件: src/redis-server ./redis.conf |
---|
 |
2. 连接服务 进入src目录:cd /usr/oop/redis/redis-4.0.0/src 执行redis-cli: ./redis-cli |
---|
 |
03. windows中启动和停止Redis服务
1. 启动服务 |
---|
 |
2. 启动客户端 |
---|
  |
⑤:设置Redis服务连接密码
Redis 默认连接服务是不需要密码的
01. 修改配置文件
修改配置文件( redis.conf)
1. 进入到 /usr/oop/redis/redis-4.0.0 目录下
2. vim redis.conf
3. 添加以下内容(密码为root)
4. requirepass root
1. 修改配置文件 设置密码 保存退出 |
---|
 |
02. 重新启动服务并连接
1. 先查找进程ID 并结束该进程
查找命令: ps -ef | grep redis
结束进程: kill -9 77246

2. 重新启动服务
进入目录 cd /usr/oop/redis/redis-4.0.0
执行redis-server并加载文件: src/redis-server ./redis.conf

3. 启动客户端
进入src目录:cd /usr/oop/redis/redis-4.0.0/src
执行redis-cli: ./redis-cli -h localhost -p 6379

4. 执行keys * 试试 (会报错,还没有认证) |
---|
 |
5. 连接的同时进行密码认证 指令:./redis-cli -h localhost -p 6379 -a root |
---|
 |
⑥:设置Redis允许远程连接
01. windows中远程连接Linux中Redis
1. 默认redis是不能远程连接的 |
---|
 |
02. 修该配置文件
修改配置文件( redis.conf)
1. 进入到 /usr/oop/redis/redis-4.0.0 目录下
2. vim redis.conf
3. 注释掉以下这行代码
4. bind 127.0.0.1
5. 可以添加下面这行代码(允许任何地方访问)
6. bind 0.0.0.0

1. 先查找进程ID 并结束该进程
查找命令: ps -ef | grep redis
结束进程: kill -9 77246

2. 重新启动服务
进入目录 cd /usr/oop/redis/redis-4.0.0
执行redis-server并加载文件: src/redis-server ./redis.conf

3. 启动客户端
进入src目录:cd /usr/oop/redis/redis-4.0.0/src
执行redis-cli: ./redis-cli -h localhost -p 6379

4. 再次使用windows连接 |
---|
 |
5. 如果还是连接失败 开放 6379 端口 命令: firewall-cmd --zone=public --add-port=6379/tcp --permanent 重新加载文件:firewall-cmd --reload |
---|
⑦:Redis数据类型
- Redis存储的是key-value结构的数据,其中key是字符串类型,value有5种常用的数据类型:
- 字符串string
- 哈希hash
- 列表list
- 集合set
- 有序集合sorted set

⑧:设置Redis数据库和切换数据库
01.设置Redis数据库的数量
修改配置文件
Linux修改redis.conf
windows修改redis.windows.conf

02. Redis中切换数据库
切换数据库 select index(数据库index)

⑨:设置Redis开机自启
我们也可以通过配置来实现开机自启。
首先,新建一个系统服务文件:
vim /etc/systemd/system/redis.service
内容如下:
[Unit]
Description=redis-server
After=network.target
[Service]
ExecStart=/usr/local/bin/redis-server /usr/oop/redis/redis-6.2.4/redis.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
然后重载系统服务:
systemctl daemon-reload
现在,我们可以用下面这组命令来操作redis了:
systemctl start redis
systemctl stop redis
systemctl restart redis
systemctl status redis
执行下面的命令,可以让redis开机自启:
systemctl enable redis
二、安装Redis可视化工具
①:下载
(Redis Desktop Manager)
官网下载:https://redisdesktop.com/download
网盘下载:
链接:https://pan.baidu.com/s/1MC7IBz_rYGaqMXq9jSZnwQ
提取码:Coke
②:安装(Redis Desktop Manager)
说明:Redis Desktop Manager是一款简单快速、跨平台的Redis桌面管理工具,也被称作Redis可视化工具;支持命令控制台操作,以及常用,查询key,rename,delete等操作。
1. 双击运行 |
---|
 |
2. 下一步 | 3. 我同意 |
---|
 |  |
4. 修改安装路径 |
---|
 |
③:使用方法
1.进入RedisDesktopManager的主界面 |
---|
 |
- Name:给该连接起一个名字
- Host:redis服务器的ip地址
- Port:redis服务器的端口号
- Auth:密码字段,如果redis服务器设置了密码验证,则需要填写,没有设置,为空即可
- 填写完再点击”Test Connection"进行测试,没有问题再点击OK完成连接
2. 启动windows Redis 服务 |
---|
 |
3. 连接 |
---|
 |
3.该工具支持根据筛选条件查询add new key,key,reload等 |
---|
 |
4.支持常用redis操作;如针对目标key执行rename,delete,addrow,reload value操作 |
---|
 |
5.支持命令控制台操作 |
---|
 |
④:安装(resp)可视化工具
- 个人更喜欢这个

- 傻瓜式安装,安装后的界面

三、Redis常用命令
①:字符串类型常用命令
SET key value 设置指定key的值
GET key 获取指定key的值
SETEX key seconds value 设置指定key的值,并将key的过期时间设为seconds秒
SETNX key value 只有在key不存在时设置key的值
更多命令可以参考Redis中文网
:https://www.redis.net.cn
1. Set 和 Get |
---|
 |
2. 第二次设置的值会覆盖第一次设置的值 |
---|
 |
3. SETEX key seconds value 设置指定key的值,并将key的过期时间设为seconds秒 |
---|
 |
4. SETNX key value 只有在key不存在时设置key的值 |
---|
 |
②:哈希hash操作命令
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象,常用命令:
HSET key field value 将哈希表key中的字段field的值设为value
HGET key field 获取存储在哈希表中指定字段的值
HDEL key field 删除存储在哈希表中的指定字段
HKEYS key 获取哈希表中所有字段
HVALS key 获取哈希表中所有值
HGETALL key 获取在哈希表中指定key的所有字段和值

1. HSET key field value 将哈希表key中的字段field的值设为value |
---|
 |
2. HGET key field 获取存储在哈希表中指定字段的值 |
---|
 |
3. HKEYS key 获取哈希表中所有字段**加粗样式** |
---|
 |
4. HVALS key 获取哈希表中所有值 |
---|
 |
5. HGETALL key 获取在哈希表中指定key的所有字段和值 |
---|
 |
6. HDEL key field 删除存储在哈希表中的指定字段 |
---|
 |
7. 删除多个字段 |
---|
 |
③:列表List操作命令
Redis列表是简单的字符串列表,按照插入顺序排序,常用命令:
LPUSH key value1 [value2] 将一个或多个值插入到列表头部
LRANGE key start stop 获取列表指定范围内的元素
RPOP key 移除并获取列表最后一个元素
LLEN key 获取列表长度
BRPOP key1 [key2 timeout 移出并获取列表的最后一个元素,如果列表没有元素会阻塞列表
直到等待超时或发现可弹出元素为止

1. LPUSH key value1 [value2] 将一个或多个值插入到列表头部 |
---|
 |
2. LRANGE key start stop 获取列表指定范围内的元素 |
---|
 |
3. RPOP key 移除并获取列表最后一个元素 |
---|
 |
4. LLEN key 获取列表长度 |
---|
 |
|
5. BRPOP key1 [key2 timeout 移出并获取列表的最后一个元素 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 |
---|
 |

④:无序集合set操作命令
Redis set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据,常用命令:
SADD key member1[member2] 向集合添加一个或多个成员
SMEMBERS key 返回集合中的所有成员
SCARD key 获取集合的成员数
SINTER key1 [key2] 返回给定所有集合的交集
SUNION key1 [key2] 返回所有给定集合的并集
SDIFF key1 [key2] 返回给定所有集合的差集
SREM key member1 [member2] 移除集合中一个或多个成员

1. SADD key member1[member2] 向集合添加一个或多个成员 |
---|
 |
2. SMEMBERS key 返回集合中的所有成员 |
---|
 |
3. SCARD key 获取集合的成员数 |
---|
 |
4. SINTER key1 [key2] 返回给定所有集合的交集 |
---|
 |
5. SUNION key1 [key2] 返回所有给定集合的并集 |
---|
 |
6. SDIFF key1 [key2] 返回给定所有集合的差集 |
---|
 |
7. SREM key member1 [member2] 移除集合中一个或多个成员 |
---|
 |
⑤:有序集合sorted set操作命令
- Redis sorted set有序集合是string类型元素的集合,且不允许重复的成员。
- 每个元素都会关联一个double类型的分数(score)。
- redis正是通过分数来为集合中的成员进行从小到大排序。
- 有序集合的成员是唯一的,但分数却可以重复。
常用命令:
ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数
ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合中指定区间内的成员
ZINCRBY key increment member 有序集合中对指定成员的分数加上增量increment
ZREM key member [member ...] 移除有序集合中的一个或多个成员

1. ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数 |
---|
 |
2. ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合中指定区间内的成员 |
---|
 |
3. ZINCRBY key increment member 有序集合中对指定成员的分数加上增量increment |
---|
 |
4. ZREM key member [member ...] 移除有序集合中的一个或多个成员 |
---|
 |
⑥:Redis通用命令
KEYS pattern 查找所有符合给定模式(pattern)的key
EXISTS key 检查给定key是否存在
TYPE key 返回key所储存的值的类型
TTL key 返回给定key的剩余生存时间(TTL,time to live),以秒为单位
DEL key 该命令用于在key存在是删除key
1. KEYS pattern 查找所有符合给定模式(pattern)的key |
---|
 |
2. EXISTS key 检查给定key是否存在 |
---|
 |
3. TYPE key 返回key所储存的值的类型 |
---|
 |
4. TTL key 返回给定key的剩余生存时间(TTL,time to live),以秒为单位 |
---|
 |
5. DEL key 该命令用于在key存在是删除key |
---|
 |
⑦:key的层级格式
Redis没有类似MySQL中的Table的概念,我们该如何区分不同类型的key呢?
例如,需要存储用户、商品信息到redis,有一个用户id是1,有一个商品id恰好也是1,此时如果使用id作为key,那就会冲突了,该怎么办?
我们可以通过给key添加前缀加以区分,不过这个前缀不是随便加的,有一定的规范:
Redis的key允许有多个单词形成层级结构,多个单词之间用’:'隔开,格式如下:
项目名:业务名:类型:id
这个格式并非固定,也可以根据自己的需求来删除或添加词条。这样以来,我们就可以把不同类型的数据区分开了。从而避免了key的冲突问题。
例如我们的项目名称叫 heima,有user和product两种不同类型的数据,我们可以这样定义key:
如果Value是一个Java对象,例如一个User对象,则可以将对象序列化为JSON字符串后存储:
set coke:user:1 '{“id”:1, “name”: “Jack”, “age”: 21}'
set coke:product:1 '{“id”:1, “name”: “小米11”, “price”: 4999}'
KEY | VALUE |
---|
coke:user:1 | {“id”:1, “name”: “Jack”, “age”: 21} |
coke:product:1 | {“id”:1, “name”: “小米11”, “price”: 4999} |
并且,在Redis的桌面客户端中,还会以相同前缀作为层级结构,让数据看起来层次分明,关系清晰:

四、在Java中操作Redis
①:介绍

②:jedis

01. 在Java中使用jedis操作Redis
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.2.3</version>
</dependency>
1. 创建一个测试类 |
---|
 |
@Test
public void JedisTest(){
Jedis jedis = new Jedis( "localhost", 6379);
jedis.set("name","zhangsan");
String name = jedis.get("name");
System.out.println(name);
jedis.hset("hset","age","23");
String age = jedis.hget("hset", "age");
System.out.println(age);
String[] keys = {"name","hset"};
long del = jedis.del(keys);
System.out.println(del);
jedis.close();
}

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.0</version>
</dependency>
4. 再次测试 |
---|
 |
③:Jedis连接池
Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此我们推荐大家使用Jedis连接池代替Jedis的直连方式。
package com.it.utils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisConnectionFatory {
private static final JedisPool jedisPool;
static {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(8);
poolConfig.setMaxIdle(8);
poolConfig.setMinIdle(0);
poolConfig.setMaxWaitMillis(1000);
jedisPool = new JedisPool(poolConfig, "192.168.100.200", 6379, 1000);
}
public static Jedis getJedis(){
return jedisPool.getResource();
}
}

④: Spring Data Redis
01. 介绍
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实现
SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:

在Spring Boot项目中,可以使用Spring Data Redis来简化Redis操作
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.8.1</version>
</dependency>
Spring Data Redis中提供了一个高度封装的类:RedisTemplate,针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:
- ValueOperations:简单K-V操作
- SetOperations:set类型数据操作
- ZSetOperations:Zset类型数据操作
- HashOperations:针对map类型的数据操作
- ListOperations:针对list类型的数据操作
02. 创建SpringBoot工程
1. 创建一个springBoot工程 |
---|
 |
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.8.1</version>
</dependency>
spring:
application:
name: springBoot_04_redis
redis:
host: localhost
port: 6379
database: 0
jedis:
pool:
max-active: 8
max-wait: 1ms
max-idle: 4
min-idle: 0
- SpringBoot04RedisApplicationTests
@SpringBootTest
@RunWith(SpringRunner.class)
class SpringBoot04RedisApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
}
}
03.测试
@SpringBootTest
@RunWith(SpringRunner.class)
class SpringBoot04RedisApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
ValueOperations opsForValue = redisTemplate.opsForValue();
opsForValue.set("name","zhangsan");
String name = (String) opsForValue.get("name");
System.out.println(name);
}
}

04. 解决序列化问题
3. 问题 |
---|
 |
4 解决方法一:(指定泛型) |
---|
  |
5. 解决方法二(配置RedisConfig)配置类 |
---|
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}
⑤:数据类型操作
01. 操作字符串类型
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
ValueOperations opsForValue = redisTemplate.opsForValue();
opsForValue.set("name2","xiaoming");
String name = (String) opsForValue.get("name2");
opsForValue.set("age","23",60L, TimeUnit.SECONDS);
Object age = opsForValue.get("age");
opsForValue.setIfAbsent("age",23);
System.out.println("姓名: " + name + " 年龄: " +age);
}
02. 操作hash类型操作
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testHash(){
HashOperations hashOperations = redisTemplate.opsForHash();
hashOperations.put("001","name","zhangsan");
hashOperations.put("001","age","23");
hashOperations.put("001","address","henan");
Object name = hashOperations.get("001", "name");
System.out.println(name);
Set keys = hashOperations.keys("001");
System.out.println("keys = " + keys);
List values = hashOperations.values("001");
System.out.println("values = " + values);
}

03. 操作List类型数据
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testList(){
ListOperations listOperations = redisTemplate.opsForList();
listOperations.leftPush("myList","a");
listOperations.leftPushAll("myList","b","c","d");
List<String> myList = listOperations.range("myList", 0, -1);
for (String value : myList) {
System.out.print("value = " + value +" ");
}
System.out.println();
int len = listOperations.size("myList").intValue();
for (int i = 0; i < len; i++) {
String value2 = (String) listOperations.rightPop("myList");
System.out.print("value2 = " + value2 +" ");
}
}

04. 操作set类型的数据
@Autowired
private RedisTemplate redisTemplate;
@Test
public void tetsSet(){
SetOperations setOperations = redisTemplate.opsForSet();
setOperations.add("values","a", "a", "b", "b", "c", "d");
Set<String> mySet = setOperations.members("values");
System.out.println("mySet = " + mySet);
setOperations.remove("values","a","b");
Set<String> mySet2 = setOperations.members("values");
System.out.println("mySet2 = " + mySet2);
}

05. 操作sorted set类型数据
@Test
public void testZSet(){
ZSetOperations zSetOperations = redisTemplate.opsForZSet();
zSetOperations.add("myZSet","a",1.0);
zSetOperations.add("myZSet","b",2.0);
zSetOperations.add("myZSet","c",3.0);
zSetOperations.add("myZSet","a",4.0);
Set<String> myZSet = zSetOperations.range("myZSet", 0, -1);
System.out.println("myZSet = " + myZSet);
zSetOperations.incrementScore("myZSet","b",10.0);
Set<String> myZSet2 = zSetOperations.range("myZSet", 0, -1);
System.out.println("myZSet2 = " + myZSet2);
zSetOperations.remove("myZSet", "a","c");
Set<String> myZSet3 = zSetOperations.range("myZSet", 0, -1);
System.out.println("myZSet3 = " + myZSet3);
}

06. 通用操作
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testPublic(){
Set<String> keys = redisTemplate.keys("*");
System.out.println("keys = " + keys);
Boolean myZSet = redisTemplate.hasKey("myZSet");
System.out.println("myZSet = " + myZSet);
Boolean myZSet1 = redisTemplate.delete("myZSet");
System.out.println("myZSet1 = " + myZSet1);
DataType mySet = redisTemplate.type("mySet");
System.out.println("mySet.name() = " + mySet.name());
}
