日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

Redis序列化存儲(chǔ)及日期格式的問(wèn)題處理_Redis

作者:段某人... ? 更新時(shí)間: 2022-03-19 編程語(yǔ)言

Redis序列化存儲(chǔ)及日期格式

在模塊開(kāi)發(fā)中,使用Redis做緩存是非常常見(jiàn)的技術(shù),當(dāng)我們注入RedisTempate模板時(shí)

redisTemplate.opsForValue().set("item_"+id,itemModel,10, TimeUnit.MINUTES);

key我們可以用固定開(kāi)頭和商品id進(jìn)行拼接,當(dāng)然正常的項(xiàng)目開(kāi)發(fā)中最好使用多級(jí)目錄進(jìn)行分類,這里只做演示使用

可視化界面看到保存的數(shù)據(jù)是這樣的

在這里插入圖片描述

這樣的數(shù)據(jù)是很不容易閱讀的,原因是Redis默認(rèn)使用的是JAVA序列化方式,在序列化時(shí)使用了Redis協(xié)議中的編碼。

不過(guò)在這種痛苦的數(shù)據(jù)面前做調(diào)試等工作無(wú)疑是非常不舒服的

這時(shí)候就需要我們自定義序列化方式

@Configuration
public class RedisConfig {
    /**
     * 修改Redis默認(rèn)的序列化方式,默認(rèn)文件在RedisAutoConfiguration
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //設(shè)置key的序列化方式為string
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        //設(shè)置value的序列化方式為json
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //定制化關(guān)于時(shí)間格式序列化問(wèn)題
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(DateTime.class,new JodaDateTimeJsonSerializer());
        simpleModule.addDeserializer(DateTime.class,new JodaDateTimeJsonDeSerializer());
        objectMapper.registerModule(simpleModule);
        //在保存結(jié)果中加入類信息,方便解析數(shù)據(jù)
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        return redisTemplate;
    }
}
public class JodaDateTimeJsonSerializer extends JsonSerializer<DateTime> {
    @Override
    public void serialize(DateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeString(value.toString("yyyy-MM-dd HH:mm:ss"));
    }
}
public class JodaDateTimeJsonDeSerializer extends JsonDeserializer<DateTime> {
    @Override
    public DateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        String s = p.readValueAs(String.class);
        DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
        return DateTime.parse(s,dateTimeFormatter);
    }
}

在這里插入圖片描述

Redis序列化LocalDateTime報(bào)錯(cuò)

實(shí)體類日期字段使用LocalDateTime,在Redis序列化時(shí)報(bào)錯(cuò),會(huì)往Redis中寫(xiě)入如下數(shù)據(jù):

"createTime": {
  "date": {
    "year": 2019,
    "month": "MAY",
    "day": 15,
    "prolepticMonth": 24232,
    "era": [
      "java.time.chrono.IsoEra",
      "CE"
    ],
    "dayOfYear": 135,
    "dayOfWeek": "WEDNESDAY",
    "leapYear": false,
    "dayOfMonth": 15,
    "monthValue": 5,
    "chronology": {
      "id": "ISO",
      "calendarType": "iso8601"
    }
  },
  "time": {
    "hour": 11,
    "minute": 3,
    "second": 43,
    "nano": 758000000
  },
  "dayOfYear": 135,
  "dayOfWeek": "WEDNESDAY",
  "month": "MAY",
  "dayOfMonth": 15,
  "year": 2019,
  "monthValue": 5,
  "hour": 11,
  "minute": 3,
  "second": 43,
  "nano": 758000000,
  "chronology": [
    "java.time.chrono.IsoChronology",
    {
      "id": "ISO",
      "calendarType": "iso8601"
    }
  ]
}

方案一:實(shí)體類日期字段添加注解

每個(gè)LocalDateTime類型字段都需要添加,不建議使用

@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime birthday;

方案二:設(shè)置Redis對(duì)日期序列化處理

添加配置:

// 日期序列化處理
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
om.registerModule(new Jdk8Module())
  .registerModule(new JavaTimeModule())
  .registerModule(new ParameterNamesModule());

完整配置:

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 配置連接工廠
        template.setConnectionFactory(factory);
        //使用Jackson2JsonRedisSerializer來(lái)序列化和反序列化redis的value值(默認(rèn)使用JDK的序列化方式)
        Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域,field,get和set,以及修飾符范圍,ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化輸入的類型,類必須是非final修飾的,final修飾的類,比如String,Integer等會(huì)跑出異常
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jacksonSeial.setObjectMapper(om);
        // 值采用json序列化
        template.setValueSerializer(jacksonSeial);
        //使用StringRedisSerializer來(lái)序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        // 設(shè)置hash key 和value序列化模式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jacksonSeial);
        template.afterPropertiesSet();
        // 日期序列化處理
        om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        om.registerModule(new Jdk8Module())
                .registerModule(new JavaTimeModule())
                .registerModule(new ParameterNamesModule());
        return template;
    }
}

原文鏈接:https://blog.csdn.net/qq_15038565/article/details/108418122

欄目分類
最近更新