zoukankan      html  css  js  c++  java
  • spring-data-redis序列化实践笔记

    (一)spring data redis 提供了多种可选择策略(RedisSerializer)
    • JdkSerializationRedisSerializer:POJO对象的存取场景,使用JDK本身序列化机制,将pojo类通过ObjectInputStream/ObjectOutputStream进行序列化操作,最终redis-server中将存储字节序列。是目前最常用的序列化策略。

    • StringRedisSerializer:Key或者value为字符串的场景,根据指定的charset对数据的字节序列编码成string,是“new String(bytes, charset)”和“string.getBytes(charset)”的直接封装。是最轻量级和高效的策略。

    • JacksonJsonRedisSerializer:jackson-json工具提供了javabean与json之间的转换能力,可以将pojo实例序列化成json格式存储在redis中,也可以将json格式的数据转换成pojo实例。因为jackson工具在序列化和反序列化时,需要明确指定Class类型,因此此策略封装起来稍微复杂。【需要jackson-mapper-asl工具支持】

    • OxmSerializer:提供了将javabean与xml之间的转换能力,目前可用的三方支持包括jaxb,apache-xmlbeans;redis存储的数据将是xml工具。不过使用此策略,编程将会有些难度,而且效率最低;不建议使用。【需要spring-oxm模块的支持】



     spring-data-redis提供了多种serializer策略,这对使用jedis的开发者而言,实在是非常便捷。sdr提供了4种内置的serializer:

    • JdkSerializationRedisSerializer:使用JDK的序列化手段(serializable接口,ObjectInputStrean,ObjectOutputStream),数据以字节流存储
    • StringRedisSerializer:字符串编码,数据以string存储
    • JacksonJsonRedisSerializer:json格式存储
    • OxmSerializer:xml格式存储

        其中JdkSerializationRedisSerializer和StringRedisSerializer是最基础的序列化策略,其中“JacksonJsonRedisSerializer”与“OxmSerializer”都是基于stirng存储,因此它们是较为“高级”的序列化(最终还是使用string解析以及构建java对象)。

        RedisTemplate中需要声明4种serializer,默认为“JdkSerializationRedisSerializer”:

        1) keySerializer :对于普通K-V操作时,key采取的序列化策略
        2) valueSerializer:value采取的序列化策略
        3) hashKeySerializer: 在hash数据结构中,hash-key的序列化策略
        4) hashValueSerializer:hash-value的序列化策略

        无论如何,建议key/hashKey采用StringRedisSerializer。

        接下来,通过实例描述如何使用它们,可以首先参考“spring-data-redis特性”:




    (二)尝试其中三种

        @Bean
        public RedisTemplate<String, Object> jdkRedisTemplate(
                RedisConnectionFactory factory) {
            RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
            template.setConnectionFactory(factory);
    
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
                ObjectMapper om = new ObjectMapper();
                om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
                om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
    
            JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
    
            StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    
            template.setValueSerializer(jdkSerializationRedisSerializer);
            template.setKeySerializer(stringRedisSerializer);
    
            template.setHashKeySerializer(stringRedisSerializer);
            template.setHashValueSerializer(jdkSerializationRedisSerializer);
    
            template.afterPropertiesSet();
            return template;
        }


        @Resource(name = "jdkRedisTemplate")   // if stringRedisTemplate, result in SmsCheck cannot be cast to java.lang.String
        private RedisTemplate<String, Object> jdkRedisTemplate;



        @RequestMapping(value = "testRedis", method = RequestMethod.POST)
        @ResponseBody
        @ApiImplicitParams({})
        @ApiOperation(value="testRedis")
        public Object testRedis() {
    
            SmsCheck smsCheck = new SmsCheck();
            smsCheck.setMobile("xxx");
    
            // 设置缓存
            jdkRedisTemplate.opsForValue().set("test",smsCheck);
    
    
            return null;
        }

    @Entity
    public class SmsCheck implements Serializable {
    	private static final long serialVersionUID = 1L;
    
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	@Column(name = "sms_check_id")
    	private int smsCheckId;
    
    	private String mobile;
    
    	。。。。。。
    



    仅对value操作,保持key为string序列化

    1.jdk序列化方案

    get test 显示

    "xacxedx00x05srx00x1ecom.ilex.xxx.model.SmsCheckx00x00x00x00x00x00x00x01x02x00x05Ix00 smsCheckIdLx00acontenttx00x12Ljava/lang/String;Lx00 createDatetx00x10Ljava/util/Date;Lx00x06mobileqx00~x00x01Lx00x04typeqx00~x00x01xpx00x00x00x00pptx00x03xxxp"


    注意:若这里的SmsCheck未实现Serializable接口,会抛出一个异常



    2.string

    直接抛出异常

    SmsCheck cannot be cast to java.lang.String



    3 json
     

    "["com.xxx.xx.model.SmsCheck",{"smsCheckId":0,"mobile":"xxx","type":null,"content":null,"createDate":null}]"




    然后将key的序列化改为jdk

    1) "xacxedx00x05tx00x04test"

    2) "test"


    显示key也被jdk序列化了



    redistemplate 默认用jdk序列化key和value
    stringredistemplate默认用string序列化key和value


    (三)关于序列化后redis视图主要参考此贴:


    最近在开始在学习Redis以及如何在Java当中去使用Redis,Redis是什么我这里就不说了。

    我主要想说的是Redis和Java当中Spring结合起来的时候,使用到的RedisTemplate和StringRedisTemplate

    他们两者之间的区别,以及该怎么使用。

    RedisTemplate看这个类的名字后缀是Template,如果了解过Spring如何连接关系型数据库的,大概不会难猜出这个类
    是做什么的 ,它跟JdbcTemplate一样封装了对Redis的一些常用的操作,当然StringRedisTemplate跟RedisTemplate功能类似
    那么肯定就会有人问,为什么会需要两个Template呢,一个不就够了吗?
    其实他们两者之间的区别主要在于他们使用的序列化类。
    RedisTemplate使用的是JdkSerializationRedisSerializer
    StringRedisTemplate使用的是StringRedisSerializer

    RedisTemplate使用的序列类在在操作数据的时候,比如说存入数据会将数据先序列化成字节数组
    然后在存入Redis数据库,这个时候打开Redis查看的时候,你会看到你的数据不是以可读的形式
    展现的,而是以字节数组显示,类似下面

    当然从Redis获取数据的时候也会默认将数据当做字节数组转化,这样就会导致一个问题,当需要获取的
    数据不是以字节数组存在redis当中而是正常的可读的字符串的时候,比如说下面这种形式的数据


     

    关于RedisTemplate和StringRedisTemplate




    (四)另外:

    spring-data-redis是对jedis的封装,如果直接使用jedis,需手动
    1序列化对象
    2转为json字符串
    使用,spring自动处理了


  • 相关阅读:
    IntelliJ IDEA注册码
    linux中patch命令 -p 选项
    设备文件简介
    《算法导论》——矩阵
    《算法导论》——数论
    linux常用查看硬件设备信息命令(转载)
    netstat和telnet命令在Windows7中的用法(转载)
    c++容器使用总结(转载)
    离散数学——数论算法
    c语言中内存对齐问题
  • 原文地址:https://www.cnblogs.com/silyvin/p/9106761.html
Copyright © 2011-2022 走看看