当前位置: 首页 > news >正文

Redis专题-基础篇

题记

本文涵盖了Redis的各种数据结构和命令,Redis的各种常见Java客户端的应用和最佳实践

jedis案例github地址:https://github.com/whltaoin/fedis_java_demo

SpringbootDataRedis案例github地址:https://github.com/whltaoin/springbootDataRedis_demo

一、初始Redis

SQL与NoSQL对比

  1. 结构化(Structured)对比
    1. SQL具有严格的结构化格式(左图)
    2. NoSQL的数据存储格式相对随意(右图)

  1. 关系对比
    1. SQL在表和表间**可能存在联系**,在操作一张表时,需要考虑对应关联表的完整性。

2. NoSQL数据间是**<font style="color:#DF2A3F;">无关联</font>**的,(下图为存储方式)

  1. 查询对比
    1. SQL查询有**固定的语法**,只要是SQL都可以使用相同的语句查询。

2. NoSQL没有固定的语法,每个NoSQL都有自己的语法糖(下图为查询同一个东西,出现了不同的语法)

  1. SQL需要满足**事务的ACID特性**(原子性、一致性、隔离性、持久性)
  2. NoSQL只是**基本满足事务的ACID**
  3. 差异总结:

初始Redis

  1. 简介

Redis(远程词典服务器),是一个基于内存的**键值型NoSQL**数据库

  1. 特征:
    1. 键值型:key-value
    2. 单线程:命令具有原子性
    3. 低延迟、数据块原因:(基于**内存**、IO多路复用、良好的编码)
    4. 支持数据持久化
    5. 支持主从集群(主服务器和副服务器)、分片集群(将数据拆分,分别存在不同的服务器上)
    6. 支持多语言客户端(java、C…)

安装Redis(Linux安装)

忽略…

二、Redis常见命令

数据类型介绍

  1. String
    1.
  2. Hash
    1. 哈希表
  3. List
    1. 有序集合,本质是链表
  4. Set
    1. 无序集合,不可重复
  5. SortedSet
    1. 有序集合,不可重复
  6. GEO
    1. 地理坐标

通用命令

  1. 查询所有通用命令:
help @generic

  1. 查看符合模版的所有key
    1. 注意:不建议在生产环境设备上使用该命令,因为模糊查询,效率不高且浪费资源

# 语法
keys +[pattern]

  1. 删除key
    1. 可以单个删除,也可以多个一起删除
del [key]

删除一个或多个示例

  1. 判断key是否存在
    1. 可以判断单个,也可以判断多个
exists [key]

判断单个和多个示例

  1. 给key设置有效期,到期后自动删除(单位秒)
    1. TTL查看可以的有效时间
expire [key] [seconds]
ttl key

示例:设置age1的有效期为10s,到期后自动删除

  1. 总结

String类型

  1. set

  1. get

  1. mset

  1. mget

  1. incr

  1. incrby

  1. incrbyfloat

  1. setnx(新增,存在则不创建)
    1. 等价于:set [key value] nx

  1. setex
    1. 等价于:set

Key的层级格式

  1. 思考:

  1. 解决方法

  1. 示例

heima:user:1
herma:product:1

层级结构:

Hash类型

  1. Hash类型(散列),其中的value是一个**无序字典**
    1. 类似于java 中的HashMap结构
  2. 使用场景:
    1. 当要修改JSON数据中某个属性的值时,使用String存储的需要重新覆盖数据,而我们的需求只是**想要修改某个值**
  3. 常用命令

  1. 示例
    1. hset

2. hget

3. hmset

4. hmget

5. hgetall

6. hkeys

7. hvals 

8. hincrby

9. hsetnx(已存在,不新建)

List类型

  1. Redis中的List类型于java中的LinkedList类似,可以当它是一个双向链表结构。
    1. 既可以支持正向检索也可以支持反向检索。
  2. 特征:
    1. 有序
    2. 元素可重复
    3. 插入和删除快
    4. 查询速度一般
  3. 使用场景举例:
    1. 朋友圈点赞列表,评论列表等
  4. 常用命令:

1. 示例:

Set类型

  1. Redis的Set结构和Java中的HashSet类似,可以看做一个value为null的HashMap。
  2. 特征:
    1. 无序
    2. 元素不可重复
    3. 查找快
    4. 支持交集、并集、差集等功能
  3. 单个set常见命令

1. 示例

  1. 多个set操作命令
    1. 求交集(sinter):两集合公共的

2. 求并集(sunion):所有元素合并

3. 求差集(sdiff):set中有,但是set2中没有

  1. 练习题:

1. 张三的好友人数

2. 张三和李四的共同好友

3. 查询那些人是张三的好友但是不是李四的好友

4. 查询张三和李四的共同好友

5. 判断李四是否是张三的好友

6. 判断张三是否是李四的好友

7. 将李四从张三的好友列表中移除

SortedSet类型

  1. 特性:
    1. 可排序
    2. 元素不可重复
    3. 查询快
  2. 应用场景:
    1. 因为可排序,常用于实现**排行榜**功能
  3. 常用命令

  1. 练习题:

1. 添加数据

2. 删除Tom

3. 获取Amy分数

4. 获取Rose排名

5. 查询80分以上人数

6. 给Amy加2分

7. 查询排名前三的同学

8. 查询80以下的同学

三、Redis的Java客户端

常用Java客户端的优缺点对比

Jedis使用(单线程)

github地址:https://github.com/whltaoin/fedis_java_demo

  1. 使用Jedis分为了四步骤:
    1. 导入依赖
    2. 初始化Jedis对象
    3. 执行Jedis中的操作方法
    4. 释放Jedis对象
  2. 具体实现
    1. 导入依赖
<?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><groupId>org.example</groupId><artifactId>jedis-test</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies>
<!--    核心--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>6.0.0</version></dependency>
<!--      测试类--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies></project>
b. 测试类方法内容
package cn.varin;import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;public class JedisTest {private Jedis jedis;@Beforepublic void init(){jedis = new Jedis("ip",6379);jedis.auth("密码");jedis.select(0);}@Testpublic void StringTest(){String set = jedis.set("name", "varin");System.out.println("执行set后结果为:"+set);String name = jedis.get("name");System.out.println("key为name的value为:"+name);}@Afterpublic void close(){if(jedis !=null){jedis.close();}}}
3. 执行结果

Jedis使用(使用连接池)

github地址:https://github.com/whltaoin/fedis_java_demo

  1. 使用步骤:
    1. 创建连接池
    2. 获取Jedis对象
    3. 操作Jedis对象
    4. 归还连接池对象
  2. 具体代码
    1. 创建连接池对象
package cn.varin.jedis.utils;import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;// Jedis连接池对象
public class JedisConnectionFactory {//static  public final JedisPool jedisPool;static {// 创建配置JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();// 最大连接数jedisPoolConfig.setMaxTotal(10);// 最大空闲数jedisPoolConfig.setMaxIdle(10);// 最小空闲数jedisPoolConfig.setMinIdle(2);// 空闲等待时间jedisPoolConfig.setMaxWaitMillis(1000);jedisPool = new JedisPool(jedisPoolConfig,"host",6379,100,"password");}public static Jedis getResource(){return jedisPool.getResource();}
}
2. 测试类代码
package cn.varin;import cn.varin.jedis.utils.JedisConnectionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;public class JedisTest {private Jedis jedis;@Beforepublic void init(){jedis = JedisConnectionFactory.getResource();jedis.select(0);}@Testpublic void StringTest(){String set = jedis.set("name", "varya");System.out.println("执行set后结果为:"+set);String name = jedis.get("name");System.out.println("key为name的value为:"+name);}@Afterpublic void close(){if(jedis !=null){jedis.close();}}}
3. 执行结果:

SpringDataRedis使用

github示例案例地址:https://github.com/whltaoin/springbootDataRedis_demo

springData介绍
  1. 项目地址:https://spring.io/projects/spring-data-redis#learn

  1. Redis模版版本信息

SpringDataRedis快速入门

SpringbootDataRedis使用步骤

基本示例
  1. 导入依赖
<?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 https://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>3.4.5</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>cn.varin</groupId><artifactId>springbootDataRedis_demo</artifactId><version>0.0.1-SNAPSHOT</version><name>springbootDataRedis_demo</name><description>springbootDataRedis_demo</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>17</java.version></properties><dependencies>
<!--		springbootDataRedis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
<!--		pool2--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><annotationProcessorPaths><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></path></annotationProcessorPaths></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
  1. 配置yml
spring:data:redis:port: 6379password: passworddatabase: 0lettuce:pool:max-active: 10max-idle: 10min-idle: 0max-wait: 100mshost: address
  1. 编写测试类
package cn.varin.springbootdataredis_demo;import cn.varin.springbootdataredis_demo.pojo.User;
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.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;@SpringBootTest
class SpringbootDataRedisDemoApplicationTests {@AutowiredRedisTemplate redisTemplate;@Testvoid setTest() {ValueOperations valueOperations = redisTemplate.opsForValue();valueOperations.set("user:1",new User("varin",1).toString());Object o = valueOperations.get("user:1");System.out.println(o);}}
  1. 结果:

重构redisTemplate序列化和反序列化工具
  1. 问题

1. 在我们直接使用redisTemplate时,存入到redis的内容,是经过编译的字节,
2. 影响阅读性
3. 增加了存储空间
  1. 解决方案:
    1. 自定义序列化和反序列话的编码格式
  2. 步骤
    1. 建立template
    2. 设置连接工厂
    3. 设置序列化工具
    4. 分别对key和value设置不同的格式
package cn.varin.springbootdataredis_demo.config;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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;@Configuration
public class RedisTamplateConfig {@Beanpublic RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){RedisTemplate<String,Object> template = new RedisTemplate<>();// 设置连接工厂template.setConnectionFactory(factory);// 创建序列化工具GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();// 对keytemplate.setKeySerializer(RedisSerializer.string());template.setHashKeySerializer(RedisSerializer.string());// 对valuetemplate.setValueSerializer(genericJackson2JsonRedisSerializer);template.setHashValueSerializer(genericJackson2JsonRedisSerializer);return  template;}
}

测试类

package cn.varin.springbootdataredis_demo;import cn.varin.springbootdataredis_demo.pojo.User;
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.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;@SpringBootTest
class SpringbootDataRedisDemoApplicationTests {@AutowiredRedisTemplate redisTemplate;@Testvoid setTest() {ValueOperations valueOperations = redisTemplate.opsForValue();// value为user对象valueOperations.set("user:2",new User("varin",1));Object o = valueOperations.get("user:1");System.out.println(o);}}
  1. 测试结果

StringRedisTamplate类使用
  1. 问题:
    1. 虽然自定义序列化工具可以解决上一问题,但是修改后在JSON字符串中会多存储一个类的包名
      1. 导致增大存储的空间
  2. 解决方法,
    1. 使用StringRedisTamplate类,在加上自己使用第三方的序列化工具进行存储。
      1. 优点:在存储时不会增加额外的数据
      2. 缺点:增加少许的代码量
  3. 示例代码
@AutowiredStringRedisTemplate stringRedisTemplate;// 用于转Json格式private static  final ObjectMapper mapper = new ObjectMapper();@Testvoid StringRedisTamplateTest() throws JsonProcessingException {User user = new User("varya",1);// 转JSON格式String s = mapper.writeValueAsString(user);// 写入数据stringRedisTemplate.opsForValue().set("user:3",s);// 读取数据String s1 = stringRedisTemplate.opsForValue().get("user:3");// 反序列化User user1 = mapper.readValue(s1, User.class);System.out.println(user1);}

http://www.xdnf.cn/news/918631.html

相关文章:

  • Vue具名插槽
  • Linux(13)——Ext系列文件系统
  • Now formdata是什么?如何使用
  • RT-Thread内核组成——内核移植
  • MySQL(61)如何进行数据库分区?
  • 锁的艺术:深入浅出讲解乐观锁与悲观锁
  • 计算机操作系统(十五)死锁的概念与死锁的处理方法
  • 【高效开发工具系列】Blackmagic Disk Speed Test for Mac:专业硬盘测速工具
  • Qt6.8编译MySQL
  • Fullstack 面试复习笔记:HTML / CSS 基础梳理
  • 【物联网-ModBus-ASCII】
  • vue3项目怎么适配不同尺寸的屏幕?
  • 计算机组成与体系结构:补码数制二(Complementary Number Systems)
  • FFmpeg 实现 100 台设备同屏的高效码流压缩
  • Python-进程
  • Playwright自动化测试全栈指南:从基础到企业级实践(2025终极版)
  • 柯尼卡美能达Konica Minolta bizhub 205i打印机信息
  • 线程池封装
  • ubuntu 22.04虚拟机配置静态IP
  • springBoot 通过模板导出Excel文档的实现
  • 几种简单的排序算法(C语言)
  • clickhouse 和 influxdb 选型
  • 【Android】浅析View.post()
  • rec_pphgnetv2完整代码学习(二)
  • 机器学习监督学习实战五:六种算法对声呐回波信号进行分类
  • [yolov11改进系列]基于yolov11引入轻量级下采样ContextGuided的python源码+训练源码
  • VBA之Word应用第三章第十节:文档Document对象的方法(三)
  • LeetCode--24.两两交换链表中的结点
  • Android USB 通信开发
  • 数组名作为函数参数详解 —— 指针退化及遍历应用示例