Notas de estudio de Redis del programador de Dark Horse: conceptos básicos de Redis

escribe primero

  • Para obtener la mejor experiencia de lectura, vaya a mi blog personal para ver este artículo: https://cyborg2077.github.io/2022/10/21/RedisBasic/

Conociendo Redis

Redis es una base de datos NoSQL de clave-valor, aquí hay dos palabras clave

  • valor clave
  • No SQL

Entre ellos 键值型, los datos almacenados en Redis se almacenan en forma de pares clave-valor clave-valor, y el valor puede tener varias formas, como cadenas, valores o incluso Json.

NoSQL es una base de datos muy diferente a las bases de datos relacionales tradicionales.

Conoce NoSQL

NoSqlSe puede traducir como base de datos No solo Sql (no solo SQL) o No Sql (no Sql). Es una base de datos especial que es muy diferente de las bases de datos relacionales tradicionales, por lo que también se llama 非关系型数据库.

estructurado y no estructurado

Las bases de datos relacionales tradicionales son datos estructurados. Cada tabla tiene información de restricción estricta cuando se crea, como el nombre del campo, el tipo de datos del campo, las restricciones del campo, etc. Los datos insertados deben seguir estas restricciones.

Por otro lado, NoSQL no tiene restricciones en el formato de la base de datos, que puede ser de tipo clave-valor, tipo de documento o incluso formato gráfico.

Asociación y no asociación

A menudo hay asociaciones entre tablas en las bases de datos tradicionales. Por ejemplo, las restricciones de clave externa
y las bases de datos no relacionales no tienen relaciones de asociación. Para mantener las relaciones, confíe en la lógica comercial en el código o en el acoplamiento entre los datos.

{
  id: 1,
  name: "张三",
  orders: [
    {
       id: 1,
       item: {
	 id: 10, title: "荣耀6", price: 4999
       }
    },
    {
       id: 2,
       item: {
	 id: 20, title: "小米11", price: 3999
       }
    }
  ]
}

Por ejemplo, para mantener la relación entre Zhang San y dos pedidos de teléfonos móviles aquí, tenemos que guardar de forma redundante estos dos productos en el documento de pedido de Zhang San, que no es lo suficientemente elegante, por lo que se recomienda utilizar la lógica empresarial para mantener la relación.

modo de consulta

Las bases de datos relacionales tradicionales realizarán consultas en función de declaraciones Sql y la sintaxis tiene un estándar unificado

SELECT id, age FROM tb_user WHERE id = 1

La sintaxis de consulta de diferentes bases de datos no relacionales varía mucho

Redis:  get user:1
MongoDB: db.user.find({_id: 1})
elasticsearch:  GET http://localhost:9200/users/1

asuntos

Las bases de datos relacionales tradicionales pueden cumplir con los principios ACID de transacciones (atomicidad, consistencia, independencia y durabilidad)
y las bases de datos no relacionales no admiten transacciones, o no pueden garantizar las características de ACID, y solo pueden lograr la consistencia de costos

Resumir

sql No SQL
estructura de datos Estructurado desestructurado
asociación de datos Relacional no relacionado
modo de consulta consulta SQL no SQL
características de la transacción ÁCIDO BASE
método de almacenamiento disco Memoria
Escalabilidad vertical nivel
Escenas a utilizar 1) La estructura de datos es fija
2) Los requisitos de consistencia y seguridad no son altos
1) La estructura de datos no es fija
2) Las empresas relacionadas tienen altos requisitos de seguridad y consistencia de datos
3) Requisitos de rendimiento
  • método de almacenamiento
    • Las bases de datos relacionales se basan en el almacenamiento en disco y habrá una gran cantidad de E/S en disco, lo que tendrá un cierto impacto en el rendimiento.
    • Para las bases de datos no relacionales, sus operaciones dependen más de la memoria para funcionar, la velocidad de lectura y escritura de la memoria será muy rápida y, naturalmente, el rendimiento será mejor
  • Escalabilidad
    • El modo de clúster de base de datos relacional generalmente es maestro-esclavo, y los datos maestro-esclavo son consistentes, lo que desempeña el papel de respaldo de datos, lo que se denomina expansión vertical.
    • Las bases de datos no relacionales pueden dividir datos y almacenarlos en diferentes máquinas, lo que puede ahorrar cantidades masivas de datos y resolver el problema del tamaño de memoria limitado. Se llama escalado horizontal.
    • Las bases de datos relacionales causan muchos problemas para la consulta de datos debido a la relación entre las tablas.

Conoce Redis

Redis nació en 2009. Su nombre completo es Remote Dictionary Server. Es una base de datos NoSQL de clave-valor basada en memoria.

característica:

  • Tipo clave-valor (clave-valor), valor admite una variedad de estructuras de datos diferentes, ricas en funciones
  • De un solo subproceso, cada comando es atómico
  • Baja latencia, rápido (basado en memoria, multiplexación IO, buena codificación)
  • Persistencia de datos de soporte
  • Compatibilidad con clúster maestro-esclavo y clúster de fragmentos
  • Soporte a clientes multilingües

Autor: Antirez

Sitio web oficial de Redis: https://redis.io/

Instalar Redis

Con respecto a la instalación de Redis, hice una descripción detallada en el artículo anterior, por lo que no entraré en detalles aquí.

{% enlace Primeros pasos con Redis, https://cyborg2077.github.io/2022/10/17/ReggieRedis/, https://pic1.imgdb.cn/item/6335135c16f2c2beb100182d.jpg %}

Cliente de escritorio Redis

Después de instalar Redis, podemos operar Redis para realizar CRUD de datos. Esto requiere el uso de clientes de Redis, incluidos:

  • cliente de línea de comandos
  • Cliente de escritorio gráfico
  • cliente de programación

Cliente de línea de comandos de Redis

Una vez completada la instalación de Redis, viene con un cliente de línea de comandos: redis-cli, que se puede usar de la siguiente manera:

redis-cli [options] [commonds]

Entre las opciones comunes están:

  • -h 127.0.0.1: especifique la dirección IP del nodo redis al que conectarse, el valor predeterminado es 127.0.0.1
  • -p 6379: especifique el puerto del nodo redis que se conectará, el valor predeterminado es 6379
  • -a 123321: Especifique la contraseña de acceso de redis

Los commonds son comandos de operación de Redis, por ejemplo:

  • ping: Realice una prueba de latido con el servidor redis, y el servidor devolverá `pong normalmente

Cliente de escritorio gráfico

Paquete de instalación: https://github.com/lework/RedisDesktopManager-Windows/releases

Redis tiene 16 almacenes por defecto, numerados del 0 al 15. El número de almacenes se puede configurar a través del archivo de configuración, pero no supera los 16, y el nombre del almacén no se puede personalizar.

Si se está conectando al servicio de Redis basado en redis-cli, puede usar el comando de selección para seleccionar la base de datos:

# 选择0号数据库
select 0

Redis comandos comunes

Redis es una base de datos clave-valor típica, la clave generalmente es una cadena y el valor contiene muchos tipos de datos diferentes

Redis comandos comunes

Los comandos generales de uso común son los siguientes

Orden describir
patrón de llaves Encuentra todas las llaves que coincidan con el patrón dado
tecla EXISTE Comprobar si existe la clave dada
tecla TIPO Devuelve el tipo de valor almacenado por la clave.
clave TTL Devuelve el tiempo de vida restante (TTL, tiempo de vida) de la clave dada en segundos
tecla Supr Este comando se usa para eliminar la clave cuando la clave existe
  • KEYS: Ver todas las claves que coinciden con la plantilla
    • No se recomienda usarlo en dispositivos de entorno de producción, porque Redis es de subproceso único y bloqueará otros comandos al ejecutar consultas.Cuando la cantidad de datos es grande, usar KEYS para consultas difusas es muy ineficiente.
  • DEL: eliminar una clave especificada
    • También puede eliminar varias claves, DEL name agetanto el nombre como la edad se eliminarán
  • EXISTS: Determinar si la clave existe
    • EXISTS name, devuelve 1 si existe y devuelve 0 si no existe
  • EXPIRE: establezca un período de validez para una clave, y la clave se eliminará automáticamente cuando expire el período de validez
    • EXPIRE name 20, establezca un período de validez de 20 segundos para el nombre, y se eliminará automáticamente cuando caduque
  • TTL: Ver el período de validez restante de una clave (Time-To-Live)
    • TTL name, verifique el período de validez restante del nombre, si no se establece ningún período de validez, devuelva -1

tipo de cadena

El tipo String, es decir, el tipo string, es el tipo de almacenamiento más simple en Redis,
su valor es una cadena, pero se puede dividir en tres tipos según el formato de la cadena.

  • string: cadena normal
  • int: tipo entero, puede realizar operaciones de autoincremento y autodecremento
  • float: Tipo de coma flotante, que puede realizar operaciones de autoincremento y autodecremento
    Independientemente del formato que tenga, la capa inferior se almacena en forma de matriz de bytes, pero el método de codificación es diferente y el espacio máximo de la cadena el tipo no puede exceder 512M

Cadena de comandos comunes

Los comandos comunes de String son

Orden describir
COLOCAR Agregue o modifique un par clave-valor existente de tipo String
CONSEGUIR Obtenga el valor del tipo String según la clave
MAYORÍA Agregue múltiples pares clave-valor de tipo String en lotes
MGET Obtenga múltiples valores de tipo String según múltiples claves
INC Incrementa una clave entera en 1
INCREÍBLE Deje que una clave de número entero se incremente automáticamente y especifique el valor del paso, por ejemplo: incrby num 2, deje que el valor numérico se incremente automáticamente en 2
INCRBYFLOAT Incrementa un número de coma flotante con un valor de paso especificado
SETNX Agregue un par clave-valor de tipo String, siempre que la clave no exista, de lo contrario no se ejecutará, lo que puede entenderse como un aumento real
SIETE Agregue un par clave-valor de tipo Cadena y especifique el período de validez

Estructura clave

  • Redis no tiene un concepto similar a Table en MySQL, entonces, ¿cómo distinguimos entre diferentes tipos de Keys?
  • Por ejemplo: necesita almacenar información de usuario y producto en Redis. Hay un usuario cuya identificación es 1 y un producto cuya identificación es 1. Si la identificación se usa como clave en este momento, habrá un conflicto . ¿Qué tengo que hacer?
  • Podemos distinguir agregando un prefijo a la clave, pero este prefijo no se agrega casualmente, hay ciertas especificaciones
    • La clave de Redis permite que múltiples palabras formen una estructura jerárquica, :separadas por múltiples palabras, el formato es el siguiente
    项目名:业务名:类型:id
    
    • Este formato no es fijo, puede eliminar/agregar entradas según sus propias necesidades, de modo que podamos distinguir datos de diferentes tipos de datos, evitando así conflictos clave
    • Por ejemplo, nuestro proyecto se llama reggie, y hay dos tipos diferentes de datos, usuario y plato, podemos definir clave como esta
      • Claves relacionadas con el usuario:reggie:user:1
      • clave relacionada con el plato:reggie:dish:1
  • Si el valor es un objeto Java, como un objeto Usuario, puede serializar el objeto en una cadena JSON y almacenarlo
LLAVE VALOR
reggie:usuario:1 {“id”:1, “nombre”: “Jack”, “edad”: 21}
reggie:plato:1 {"id": 1, "nombre": "Caldo de esturión", "precio": 4999}
  • Y en el cliente de escritorio de Redis, también se usará el mismo prefijo como estructura jerárquica, para que los datos se vean jerárquicos y la relación sea clara.

tipo de hash

  • Tipo hash, también llamado hash, donde el valor es un diccionario desordenado, similar a la estructura HashMap en Java
  • La estructura String se almacena después de serializar el objeto en una cadena JSON, lo cual es muy inconveniente cuando queremos modificar el valor de un atributo del objeto.
LLAVE VALOR
reggie:usuario:1 {“id”:1, “nombre”: “Jack”, “edad”: 21}
reggie:plato:1 {"id": 1, "nombre": "Caldo de esturión", "precio": 4999}
  • La estructura Hash puede almacenar cada campo en el objeto de forma independiente y puede hacer CRUD para un solo campo
LLAVE VALOR
campo valor
reggie:usuario:1 nombre Jacobo
edad  21

reggie:usuario:2
nombre  Rosa
edad  18
  • Los comandos comunes para Hash son
Orden describir
Valor del campo clave HSET Agregar o modificar el valor del campo de la clave de tipo hash
campo clave HGET Obtener el valor de campo de una clave de tipo hash
HMSET Agregue por lotes los valores de campo de múltiples claves de tipo hash
HMGET Obtenga los valores de campo de múltiples claves de tipo hash en lotes
HGETTODO Obtener todos los campos y valores en una clave de tipo hash
HTECLAS Obtenga todos los campos en una clave de tipo hash
HINCRBY Deje que el valor de campo de una clave de tipo hash se incremente automáticamente y especifique el tamaño del paso
HSETNX Agregue un valor de campo de una clave de tipo hash, siempre que el campo no exista, de lo contrario no se ejecutará

Tipo de lista

  • Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。

  • 特征也与LinkedList类似:

    • 有序
    • 元素可以重复
    • 插入和删除快
    • 查询速度一般
  • 常用来存储一个有序数据,例如:朋友圈点赞列表,评论列表等。

  • List的常见命令有:

命令 描述
LPUSH key element … 向列表左侧插入一个或多个元素
LPOP key 移除并返回列表左侧的第一个元素,没有则返回nil
RPUSH key element … 向列表右侧插入一个或多个元素
RPOP key 移除并返回列表右侧的第一个元素
LRANGE key star end 返回一段角标范围内的所有元素
BLPOP和BRPOP 与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil

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的交集
SUNION key1 key2 … 求key1与key2的并集
SDIFF key1 key2 … 求key1与key2的差集

{% note info no-icon %}
练习题:

  1. 将下列数据用Redis的Set集合来存储:
  • 张三的好友有:李四、王五、赵六
127.0.0.1:6379> sadd zhangsan lisi wangwu zhaoliu
(integer) 3
  • 李四的好友有:王五、麻子、二狗
127.0.0.1:6379> sadd lisi wangwu mazi ergou
(integer) 3
  1. 利用Set的命令实现下列功能:
  • 计算张三的好友有几人
127.0.0.1:6379> scard zhangsan
(integer) 3
  • 计算张三和李四有哪些共同好友
127.0.0.1:6379> sinter zhangsan lisi
1) "wangwu"
  • 查询哪些人是张三的好友却不是李四的好友
127.0.0.1:6379> sdiff zhangsan lisi
1) "zhaoliu"
2) "lisi"
  • 查询张三和李四的好友总共有哪些人
127.0.0.1:6379> sunion zhangsan lisi
1) "wangwu"
2) "zhaoliu"
3) "ergou"
4) "lisi"
5) "mazi"
  • 判断李四是否是张三的好友
127.0.0.1:6379> sismember zhangsan lisi
(integer) 1
  • 判断张三是否是李四的好友
127.0.0.1:6379> sismember lisi zhangsan
(integer) 0
  • 将李四从张三的好友列表中移除
127.0.0.1:6379> srem zhangsan lisi
(integer) 1

{% endnote %}

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 求差集、交集、并集

{% note warning no-icon %}
注意:所有的排名默认都是升序,如果要降序则在命令的Z后面添加REV即可,例如:

  • 升序获取sorted set 中的指定元素的排名:ZRANK key member
  • 降序获取sorted set 中的指定元素的排名:ZREVRANK key memeber
    {% endnote %}

{% note info no-icon %}

  • 练习题:
    • 将班级的下列学生得分存入Redis的SortedSet中:
    • Jack 85, Lucy 89, Rose 82, Tom 95, Jerry 78, Amy 92, Miles 76
    127.0.0.1:6379> zadd stu 85 Jack 89 Lucy 82 Rose 95 Tom 78 Jerry 92 Amy 76 Miles
    (integer) 7
    
    • 并实现下列功能:
      • 删除Tom同学
      127.0.0.1:6379> zrem stu Tom
      (integer) 1
      
      • 获取Amy同学的分数
      127.0.0.1:6379> zscore stu Amy
      "92"
      
      • 获取Rose同学的排名
      127.0.0.1:6379> zrank stu Rose
      (integer) 2
      
      • 查询80分以下有几个学生
      127.0.0.1:6379> zcount stu 0 80
      (integer) 2
      
      • 给Amy同学加2分
      127.0.0.1:6379> zincrby stu 2 Amy
      "94"
      
      • 查出成绩前3名的同学
      127.0.0.1:6379> zrange stu 0 2
      1) "Miles"
      2) "Jerry"
      3) "Rose"
      
      • 查出成绩80分以下的所有同学
      127.0.0.1:6379> zrangebyscore stu 0 80
      1) "Miles"
      2) "Jerry"
      

{% endnote %}

Redis的Java客户端

  • 目前主流的Redis的Java客户端有三种
    • Jedis和Lettuce:这两个主要是提供了Redis命令对应的API,方便我们操作Redis,而SpringDataRedis又对这两种做了抽象和封装,因此我们后期会直接以SpringDataRedis来学习。
    • Redisson:是在Redis基础上实现了分布式的可伸缩的java数据结构,例如Map、Queue等,而且支持跨进程的同步机制:Lock、Semaphore等待,比较适合用来实现特殊的功能需求。

Jedis客户端

快速入门

  • 使用Jedis的步骤
    1. 导入Jedis的maven坐标
    <!--jedis-->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.7.0</version>
    </dependency>
    <!--单元测试-->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.7.0</version>
        <scope>test</scope>
    </dependency>
    
    1. 建立连接
      新建一个单元测试类
    private Jedis jedis;
    
    @BeforeEach
    void setUp() {
        //1. 建立连接
        jedis = new Jedis("101.42.225.160", 6379);
        //2. 设置密码
        jedis.auth("root");
        //3. 选择库
        jedis.select(0);
    }
    
    1. 测试
    @Test
    void testString(){
        jedis.set("name","Kyle");
        String name = jedis.get("name");
        System.out.println("name = " + name);
    }
    
    @Test
    void testHash(){
        jedis.hset("reggie:user:1","name","Jack");
        jedis.hset("reggie:user:2","name","Rose");
        jedis.hset("reggie:user:1","age","21");
        jedis.hset("reggie:user:2","age","18");
        Map<String, String> map = jedis.hgetAll("reggie:user:1");
        System.out.println(map);
    }
    
    1. 释放资源
    @AfterEach
    void tearDown(){
        if (jedis != null){
            jedis.close();
        }
    }
    

连接池

  • Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此我们推荐大家使用Jedis连接池代替Jedis的直连方式。
  • 新建一个com.blog.util,用于存放我们编写的工具类
  • 但后面我们使用SpringDataRedis的时候,可以直接在yml配置文件里配置这些内容
public class JedisConnectionFactory {

    private static JedisPool jedisPool;

    static {
        // 配置连接池
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(8);
        poolConfig.setMaxIdle(8);
        poolConfig.setMinIdle(0);
        poolConfig.setMaxWaitMillis(1000);
        // 创建连接池对象,参数:连接池配置、服务端ip、服务端端口、超时时间、密码
        jedisPool = new JedisPool(poolConfig, "101.42.225.160", 6379, 1000, "root");
    }

    public static Jedis getJedis(){
        return jedisPool.getResource();
    }
}
  • 之后我们的测试类就可以修改为如下
@SpringBootTest
class RedisTestApplicationTests {

    private Jedis jedis = JedisConnectionFactory.getJedis();

    @Test
    void testString(){
        jedis.set("name","Kyle");
        String name = jedis.get("name");
        System.out.println("name = " + name);
    }

    @Test
    void testHash(){
        jedis.hset("reggie:user:1","name","Jack");
        jedis.hset("reggie:user:2","name","Rose");
        jedis.hset("reggie:user:3","name","Kyle");
        jedis.hset("reggie:user:1","age","21");
        jedis.hset("reggie:user:2","age","18");
        jedis.hset("reggie:user:3","age","18");
        Map<String, String> map = jedis.hgetAll("reggie:user:1");
        System.out.println(map);
    }

    @AfterEach
    void tearDown(){
        if (jedis != null){
            jedis.close();
        }
    }
}

SpringDataRedis客户端

  • 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封装到了不同的类型中:

API 返回值类型 说明
redisTemplate.opsForValue() ValueOperations 操作String类型数据
redisTemplate.opsForHash() HashOperations 操作Hash类型数据
redisTemplate.opsForList() ListOperations 操作List类型数据
redisTemplate.opsForSet() SetOperations 操作Set类型数据
redisTemplate.opsForzSet() ZSetOperations 操作SortedSet类型数据
redisTemplate 通用的命令

快速入门

SpringBoot已经提供了对SpringDataRedis的支持,使用起来非常简单

  1. 导入依赖,
<!--redis依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--common-pool-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>
<!--Jackson依赖-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>
<!--lombok-->
<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>
  1. 配置Redis
spring:
  redis:
    host: 101.42.225.160
    port: 6379
    password: root
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: 100ms
  1. 注入RedisTemplate
    因为有了SpringBoot的自动装配,我们可以拿来就用
@Autowired
private RedisTemplate redisTemplate;
  1. 编写测试方法
@Test
void stringTest(){
    redisTemplate.opsForValue().set("username","David");
    String username = (String) redisTemplate.opsForValue().get("username");
    System.out.println(username);
}

自定义序列化

  • RedisTemplate可以接收任意Object作为值写入Redis
  • 只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的

\xAC\xED\x00\x05t\x00\x06\xE5\xBC\xA0\xE4\xB8\x89

  • 缺点:

    • 可读性差
    • 内存占用较大
  • 我们可以自定义RedisTemplate的序列化方式,代码如下
    com.blog.config包下编写对应的配置类

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        // 创建RedisTemplate对象
        RedisTemplate<String, 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;
    }
}
  • 我们编写一个User类,并尝试将其创建的对象存入Redis,看看是什么效果
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private Integer age;
}
  • 测试方法
@Test
void stringTest(){
    redisTemplate.opsForValue().set("userdata",new User("张三",18));
}
  • 这里采用了JSON序列化来代替默认的JDK序列化方式。最终结果如下:
{
  "@class": "com.blog.entity.User",
  "name": "张三",
  "age": 18
}
  • 整体可读性有了很大提升,并且能将Java对象自动的序列化为JSON字符串,并且查询时能自动把JSON反序列化为Java对象。不过,其中记录了序列化时对应的class名称,目的是为了查询时实现自动反序列化。这会带来额外的内存开销。
  • 所以肯定会有更好的方法

StringRedisTemplate

  • 为了节省内存空间,我们可以不使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。
  • 因为存入和读取时的序列化及反序列化都是我们自己实现的,SpringDataRedis就不会将class信息写入Redis了
  • 这种用法比较普遍,因此SpringDataRedis就提供了RedisTemplate的子类:StringRedisTemplate,它的key和value的序列化方式默认就是String方式。源码如下
public class StringRedisTemplate extends RedisTemplate<String, String> {
    public StringRedisTemplate() {
        this.setKeySerializer(RedisSerializer.string());
        this.setValueSerializer(RedisSerializer.string());
        this.setHashKeySerializer(RedisSerializer.string());
        this.setHashValueSerializer(RedisSerializer.string());
    }
  • 省去了我们自定义RedisTemplate的序列化方式的步骤(可以将之前配置的RedisConfig删除掉),而是直接使用:
@Test
void stringTest() throws JsonProcessingException {
    //创建对象
    User user = new User("张三", 18);
    //手动序列化
    String json = mapper.writeValueAsString(user);
    //写入数据
    stringRedisTemplate.opsForValue().set("userdata", json);
    //获取数据
    String userdata = stringRedisTemplate.opsForValue().get("userdata");
    //手动反序列化
    User readValue = mapper.readValue(userdata, User.class);
    System.out.println(readValue);
}
  • 存入Redis中是这样的
{
  "name": "张三",
  "age": 18
}

Supongo que te gusta

Origin blog.csdn.net/qq_33888850/article/details/129770025
Recomendado
Clasificación