Heim  >  Artikel  >  Datenbank  >  So konfigurieren Sie die Reihenfolge und Deserialisierung von RedisTemplate in Redis

So konfigurieren Sie die Reihenfolge und Deserialisierung von RedisTemplate in Redis

WBOY
WBOYnach vorne
2023-06-03 21:25:081377Durchsuche

RedisTemplate-Konfigurationssequenz und Deserialisierung

Spring Data Redis bietet eine hervorragende Kapselung, um die Verwendung von Redis-Operationen zu erleichtern. Eine stark gekapselte RedisTemplate-Klasse wird bereitgestellt, um eine Reihe von Redis-Vorgängen auszuführen. Gleichzeitig wird der Verbindungspool automatisch verwaltet und der Transaktionskapselungsvorgang zur Verarbeitung an den Container übergeben.

Für die „Serialisierung und Deserialisierung“ von Daten stehen verschiedene Strategien (RedisSerializer) zur Verfügung

Standardmäßig werden JdkSerializationRedisSerializer sowie StringRedisSerializer, JacksonJsonRedisSerializer, OxmSerializer und GenericFastJsonRedisSerializer verwendet.

Einführung

JdkSerializationRedisSerializer: Das POJO-Objektzugriffsszenario verwendet den JDK-eigenen Serialisierungsmechanismus, serialisiert die Pojo-Klasse über ObjectInputStream/ObjectOutputStream und schließlich wird die Bytesequenz im Redis-Server gespeichert. Dies ist die aktuelle Standard-Serialisierungsstrategie.

StringRedisSerializer: Wenn der Schlüssel oder Wert ein String ist, wird die Bytefolge der Daten entsprechend dem angegebenen Zeichensatz in einen String codiert. Es handelt sich um eine direkte Kapselung von „new String(bytes, charset)“ und „string.getBytes“. (Zeichensatz)". ist die einfachste und effizienteste Strategie.

JacksonJsonRedisSerializer: Das Jackson-Json-Tool bietet Konvertierungsfunktionen zwischen Javabean und JSON. Es kann Pojo-Instanzen in das JSON-Format serialisieren und in Redis speichern oder Daten im JSON-Format in Pojo-Instanzen konvertieren. Da das Jackson-Tool beim Serialisieren und Deserialisieren den Klassentyp explizit angeben muss, ist die Kapselung dieser Strategie etwas komplizierter. [Erfordert Jackson-Mapper-ASL-Tool-Unterstützung]

GenericFastJsonRedisSerializer: Eine weitere Konvertierung zwischen Javabean und JSON, und der Klassentyp muss ebenfalls angegeben werden.

OxmSerializer: Bietet die Möglichkeit, Javabeans in XML zu konvertieren. Die derzeit verfügbare Unterstützung von drei Anbietern umfasst Jaxb, Apache-XMLBeans und XML-Tools. Allerdings wird die Verwendung dieser Strategie die Programmierung erschweren und ist nicht zu empfehlen. [Erfordert die Unterstützung des Spring-Oxm-Moduls]

Übung

1) Abhängigkeit (Version erbt SpringBoot-Version)

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

2) RedisConfig-Klasse

Beans hinzufügen, Schlüssel/Wert und die Reihenfolge von HashKey und angeben HashValue Enthält und deserialisiert FastJson.

package com.sleb.springcloud.common.config;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
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.GenericToStringSerializer;
/**
 * redis配置
 * @author 追到乌云的尽头找太阳(Jacob)
 **/
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 使用 GenericFastJsonRedisSerializer 替换默认序列化
        GenericFastJsonRedisSerializer genericFastJsonRedisSerializer = new GenericFastJsonRedisSerializer();
        // 设置key和value的序列化规则
        redisTemplate.setKeySerializer(new GenericToStringSerializer<>(Object.class));
        redisTemplate.setValueSerializer(genericFastJsonRedisSerializer);
        // 设置hashKey和hashValue的序列化规则
        redisTemplate.setHashKeySerializer(new GenericToStringSerializer<>(Object.class));
        redisTemplate.setHashValueSerializer(genericFastJsonRedisSerializer);
        // 设置支持事物
        redisTemplate.setEnableTransactionSupport(true);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

RedisTemplate-Serialisierungsproblem

Die Serialisierungs- und Deserialisierungsregeln sind inkonsistent, was zu Fehlerberichtsproblemen führt

1. Konfigurieren Sie redisTemplate

<!-- redis数据源 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大空闲数 -->
        <property name="maxIdle" value="${redis.maxIdle}"/>
        <!-- 最大空连接数 -->
        <property name="maxTotal" value="${redis.maxTotal}"/>
        <!-- 最大等待时间 -->
        <property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
        <!-- 返回连接时,检测连接是否成功 -->
        <property name="testOnBorrow" value="${redis.testOnBorrow}"/>
    </bean>
<!-- Spring-data-redis连接池管理工厂 -->
    <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <!-- IP地址 -->
        <property name="hostName" value="${redis.host}"/>
        <!-- 端口号 -->
        <property name="port" value="${redis.port}"/>
        <!-- 密码 -->
<!--        <property name="password" value="${redis.password}"/>-->
        <!-- 超时时间 默认2000 -->
        <property name="timeout" value="${redis.timeout}"/>
        <!-- 连接池配置引用 -->
        <property name="poolConfig" ref="poolConfig"/>
        <!-- 是否使用连接池 -->
        <property name="usePool" value="true"/>
        <!-- 指定使用的数据库 -->
        <property name="database" value="0"/>
    </bean>
<!-- redis template definition -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="jedisConnectionFactory"/>
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
        </property>
        <property name="hashKeySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>
        <property name="hashValueSerializer">
            <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
        </property>
    </bean>

2. Speichern Sie den Wert

Dieses Mal wird die Rückruffunktion von redisTemplate verwendet Wert, der auf Zeichen basiert. String-Serialisierungsmethode zum Speichern von redisValue

    public void testRedisListPush() {
        String redisKey = "testGoodsKey";
        List<String> redisValues = Arrays.asList("10002001", "10002002");
        // 使用管道向redis list结构中批量插入元素
        redisTemplate.executePipelined((RedisConnection redisConnection) -> {
            // 打开管道
            redisConnection.openPipeline();
            // 给本次管道内添加,一次性执行的多条命令
            for (String redisValue : redisValues) {
                redisConnection.rPush(redisKey.getBytes(), redisValue.getBytes());
            }
            return null;
        });
    }

redis-Client: Wert ist eine Zeichenfolge

So konfigurieren Sie die Reihenfolge und Deserialisierung von RedisTemplate in Redis

3. Holen Sie sich den Wert

Dieses Mal ist das zurückgegebene Ergebnis standardmäßig die in 1 konfigurierte JdkSerializationRedisSerializer-Serialisierungsmethode . Konfigurieren Sie redisTemplate. Da die Serialisierungsmethoden zum Speichern und Abrufen nicht einheitlich sind, treten Fehler auf.

	public void testRedisListPop() {
        String redisKey = "testGoodsKey";
        // 使用管道从redis list结构中批量获取元素
        List<Object> objects = redisTemplate.executePipelined((RedisConnection redisConnection) -> {
            // 打开管道
            redisConnection.openPipeline();
            for (int i = 0; i < 2; i++) {
                redisConnection.rPop(redisKey.getBytes());
            }
            return null;
        });
        System.out.println(objects);
    }

Fehlerdetails: Deserialisierung fehlgeschlagen


org.springframework.data.redis.serializer.SerializationException: Deserialisieren nicht möglich; verschachtelte Ausnahme ist org.springframework.core.serializer.support.SerializationFailedException: Die Nutzlast konnte nicht deserialisiert werden Array ein Ergebnis der entsprechenden Serialisierung für DefaultDeserializer?; verschachtelte Ausnahme ist java.io.StreamCorruptedException: ungültiger Stream-Header: 31303030
...
Verursacht durch: org.springframework.core.serializer.support.SerializationFailedException: Fehler beim Deserialisieren der Nutzlast das Byte-Array ein Ergebnis der entsprechenden Serialisierung für DefaultDeserializer?; verschachtelte Ausnahme ist java.io.StreamCorruptedException: ungültiger Stream-Header: 31303030
bei org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:78)
bei org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:36)
bei org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:80)
... 39 weitere
Verursacht von: java.io.StreamCorruptedException: ungültiger Stream-Header: 31303030
bei java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:899)
bei java.io.ObjectInputStream.(ObjectInputStream.java:357)
bei org.springframework.core.ConfigurableObjectInputStream.(ConfigurableObjectInputStream.java:63)
bei org.springframework.core.ConfigurableObjectInputStream.(ConfigurableObjectInputStream.java:49)
bei org.springframework.core . Serializer. DefaultDeserializer.deserialize(DefaultDeserializer.java:68)
bei org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:73)
... 41 weitere

Solution

1. Get Value

需要在redisTemplate.executePipelined入参中再加一个参数:redisTemplate.getStringSerializer(),取值成功,解决问题!!

    public void testRedisListPop() {
        String redisKey = "testGoodsKey";
        // 使用管道从redis list结构中批量获取元素
        List<Object> objects = redisTemplate.executePipelined((RedisConnection redisConnection) -> {
            // 打开管道
            redisConnection.openPipeline();
            for (int i = 0; i < 2; i++) {
                redisConnection.rPop(redisKey.getBytes());
            }
            return null;
        }, redisTemplate.getStringSerializer());
        System.out.println(objects);
    }

总结

1、使用原生redisTemplate操作数据和redisTemplate回调函数操作数据注意点:

a.原生redisTemplate操作数据

代码

    public void testRedisListPush() {
        String redisKey = "testGoodsKey";
        List<String> redisValues = Arrays.asList("10002001", "10002002");
        redisValues.forEach(redisValue -> redisTemplate.opsForList().rightPush(redisKey, redisValue));
    }

redis客户端数据展示

So konfigurieren Sie die Reihenfolge und Deserialisierung von RedisTemplate in Redis

b.redisTemplate回调函数操作数据

代码

    public void testRedisListPush() {
        String redisKey = "testGoodsKey";
        List<String> redisValues = Arrays.asList("10002001", "10002002");
        // 使用管道向redis list结构中批量插入元素
        redisTemplate.executePipelined((RedisConnection redisConnection) -> {
            // 打开管道
            redisConnection.openPipeline();
            // 给本次管道内添加,一次性执行的多条命令
            for (String redisValue : redisValues) {
                redisConnection.rPush(redisKey.getBytes(), redisValue.getBytes());
            }
            return null;
        });
    }

redis客户端数据展示

So konfigurieren Sie die Reihenfolge und Deserialisierung von RedisTemplate in Redis

c.不同点:

原生redisTemplate操作数据序列化方式是和redis配置统一的,redisTemplate回调函数操作数据序列化方式是自定义的。存值取值是需要注意。

Das obige ist der detaillierte Inhalt vonSo konfigurieren Sie die Reihenfolge und Deserialisierung von RedisTemplate in Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen