Rumah  >  Artikel  >  pangkalan data  >  Bagaimana untuk mengkonfigurasi urutan dan penyahserialisasian RedisTemplate dalam Redis

Bagaimana untuk mengkonfigurasi urutan dan penyahserialisasian RedisTemplate dalam Redis

WBOY
WBOYke hadapan
2023-06-03 21:25:081378semak imbas

Jujukan konfigurasi dan penyahserikatan RedisTemplate

Data Musim Bunga Redis menyediakan enkapsulasi yang sangat baik untuk memudahkan penggunaan operasi Redis. Kelas RedisTemplate berkapsul tinggi disediakan untuk melaksanakan satu siri operasi redis, dan kumpulan sambungan diuruskan secara automatik pada masa yang sama, operasi pengkapsulan transaksi diserahkan kepada bekas untuk diproses.

Pelbagai strategi (RedisSerializer) disediakan untuk "sirialisasi dan penyahserikatan" data

Lalainya ialah menggunakan JdkSerializationRedisSerializer, serta StringRedisSerializer, JacksonJsonRedisSerializer, OxmSerializer.Json dan GenericFast.

Pengenalan

JdkSerializationRedisSerializer: Senario capaian objek POJO, menggunakan mekanisme siri JDK sendiri, menyerikan kelas pojo melalui ObjectInputStream/ObjectOutputStream, dan akhirnya menyimpan perkataan dalam jujukan bahagian pelayan redis. Ini ialah strategi bersiri lalai semasa.

StringRedisSerializer: Apabila kunci atau nilai ialah rentetan, jujukan bait data dikodkan ke dalam rentetan mengikut set aksara yang ditentukan, iaitu "String(bait, charset) baharu" dan "string.getBytes (charset)" enkapsulasi langsung. adalah strategi yang paling ringan dan cekap.

JacksonJsonRedisSerializer: Alat jackson-json menyediakan keupayaan penukaran antara javabean dan json Ia boleh mensirikan tika pojo ke dalam format json dan menyimpannya dalam redis, atau menukar data format json kepada tika pojo. Oleh kerana alat Jackson perlu menyatakan secara eksplisit jenis Kelas semasa mensiri dan menyahsiri, strategi ini lebih rumit sedikit untuk dirangkumkan. [Memerlukan sokongan alat jackson-mapper-asl]

GenericFastJsonRedisSerializer: Satu lagi penukaran antara javabean dan json, dan jenis Kelas juga perlu dinyatakan.

OxmSerializer: Menyediakan keupayaan untuk menukar javabeans kepada xml yang tersedia pada masa ini sokongan tiga pihak termasuk jaxb, apache-xmlbeans data yang disimpan dalam redis akan menjadi alat xml. Walau bagaimanapun, menggunakan strategi ini akan menjadikan pengaturcaraan lebih sukar dan paling berkesan ia tidak disyorkan. [Memerlukan sokongan modul spring-oxm]

Amalan

1) Ketergantungan (versi mewarisi versi SpringBoot)

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

2) Kelas RedisConfig

Tambahkan kacang, nyatakan kunci/nilai dan pensirilan dan penyahsirilan HashKey dan HashValue ke dalam 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;
    }
}

Masalah bersiri RedisTemplate

Peraturan pensirilan dan penyahserilan tidak konsisten, mengakibatkan pelaporan ralat

1 Konfigurasikan redisTemplate

Nilai simpan

2 >

Kali ini nilai disimpan, fungsi panggil balik redisTemplate digunakan dan redisValue disimpan mengikut kaedah siri rentetan

<!-- 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>

redis client: value ialah rentetan

Bagaimana untuk mengkonfigurasi urutan dan penyahserialisasian RedisTemplate dalam Redis

3. Keadaan ralat berlaku.

    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;
        });
    }

Butiran ralat: Penyahserikatan gagal

org.springframework.data.redis.serializer.SerializationException: Tidak boleh desirialisasi; support.SerializationFailedException: Gagal menyahsiri muatan. Adakah tatasusunan bait adalah hasil daripada siri yang sepadan untuk DefaultDeserializer?; springframework.core.serializer.support.SerializationFailedException: Gagal menyahserialisasikan muatan: Adakah tatasusunan bait hasil daripada siri yang sepadan untuk DefaultDeserializer?; core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:78)
di org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:36)

di data org.springframework. redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:80)
... 39 lagi
Disebabkan oleh: java.io.StreamCorruptedException: pengepala strim tidak sah: 31303030.Object di InputStrioamread. (ObjectInputStream.java:899)
di java.io.ObjectInputStream.(ObjectInputStream.java:357)
di org.springframework.core.ConfigurableObjectInputStream.(ConfigurableObjectInput:6 )
di org.springframework.core.ConfigurableObjectInputStream.(ConfigurableObjectInputStream.java:49)
di org.springframework.core.serializer.DefaultDeserializer.deserialize(DefaultDeserializer)<.> at org.springframework.core.serializer.DefaultDeserializer.deserialize(DefaultDeserializer)<. org.springframework.core.serializer.support.deserializingconverter.convert> ... 41 lagi


Penyelesaian

1 >

需要在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客户端数据展示

Bagaimana untuk mengkonfigurasi urutan dan penyahserialisasian RedisTemplate dalam 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客户端数据展示

Bagaimana untuk mengkonfigurasi urutan dan penyahserialisasian RedisTemplate dalam Redis

c.不同点:

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

Atas ialah kandungan terperinci Bagaimana untuk mengkonfigurasi urutan dan penyahserialisasian RedisTemplate dalam Redis. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam