redis 存储对象的方法对比分析


Posted in Redis onAugust 02, 2021

redis 存储对象的方法对比

问题背景:

原来项目里面全部是直接redis存储对象的json数据,需要频繁的序列化和反序列化,后来考虑更换项目中的redis存储对象为hash对象存储的,但是获取后不能方便的set get操作,很是蛋疼,怎么才能解决这个问题呢?

1.1 直接存储对象的json

存放redis的时候,直接先用fastJson 或者 jackJson或者Gson把对象序列化为json数据,然后用直接存放,key表示用户id或许和openid,value则是对象的json数据

redis 存储对象的方法对比分析

public String get(String key) {
Object value = redisTemplate.boundValueOps(key).get();
return (String) value;
}
public void set(String key, String json) {
if (json == null) {
return;
}
redisTemplate.boundValueOps(key).set(json);
}

优点:虽然需要序列化和反序列化,但是可以直接操作对象的方法,方便快捷

缺点:需要序列化和反序列化,并且修改单个字段,需要获取整个json,修改后,序列化保存,浪费空间,浪费时间,效率低

1.2 采用redis hash key field value 存储

key代表主键,比如用户id,或者openId,value是一个map,对应各个字段的属性和值

redis 存储对象的方法对比分析

存放单个字段

public void hset(String key, String field, String obj) {
redisTemplate.boundHashOps(key).put(field,obj);
}

存放整个:

public void hSetMap(String key,Map<Object,Object> map){
redisTemplate.boundHashOps(key).putAll(map);
}

优点:存储方方便,节省内存空间,并且可以直接对单个字段修改,而不用获取整个对象,效率高

缺点:获取value后,是个map,不能方便的直接调用(set get)处理,需要手动map.get(filed)或者map.put(field,value)

1.3 如何解决redis hash存储对象的操作方便性问题

其实关于map和pojo的转换问题,网上给出了利用反射做的转换方法,但是加上了转换和反转,这和序列化和反序列化的问题一样了,效率问题,也不敢指直接用,纠结,思考再三,还是先维持代码不动了,以后考虑好了再说,或者广发网友有啥好解决方法,请多多指教哈!

Redis存储对象的三种方式

一、 将对象序列化后保存到Redis

序列化工具类实现

public class SerializeUtil {
    /*
     * 序列化
     * */
    public static byte[] serizlize(Object object){
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            byte[] bytes = baos.toByteArray();
            return bytes;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(baos != null){
                    baos.close();
                }
                if (oos != null) {
                    oos.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return null;
    }
    /*
     * 反序列化
     * */
    public static Object deserialize(byte[] bytes){
        ByteArrayInputStream bais = null;
        ObjectInputStream ois = null; 
        try{
            bais = new ByteArrayInputStream(bytes);
            ois = new ObjectInputStream(bais);
            return ois.readObject();
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            try {
 
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return null;
    }
}

获取jedis实例

public class RedisConnection {
    private static String HOST = "127.0.0.1";
    private static int PORT = 6379;
    private static int MAX_ACTIVE = 1024;
    private static int MAX_IDLE = 200;
    private static int MAX_WAIT = 10000;
 
    private static JedisPool jedisPool = null;
 
    /*
     * 初始化redis连接池
     * */
    private static void initPool(){
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxTotal(MAX_ACTIVE);//最大连接数
            config.setMaxIdle(MAX_IDLE);//最大空闲连接数
            config.setMaxWaitMillis(MAX_WAIT);//获取可用连接的最大等待时间
 
            jedisPool = new JedisPool(config, HOST, PORT);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /*
     * 获取jedis实例
     * */
    public synchronized static Jedis getJedis() {
        try {
            if(jedisPool == null){
                initPool();
            }
            Jedis jedis = jedisPool.getResource();
            jedis.auth("redis");//密码
            return jedis;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

redis操作类

public class RedisOps {
    public static void set(String key,String value){
        Jedis jedis = RedisConnection.getJedis();
        jedis.set(key, value);
        jedis.close();
    }
    public static String get(String key){
        Jedis jedis = RedisConnection.getJedis();
        String value = jedis.get(key);
        jedis.close();
        return value;
    }
    public static void setObject(String key,Object object){
        Jedis jedis = RedisConnection.getJedis();
        jedis.set(key.getBytes(), SerializeUtil.serizlize(object));
        jedis.close();
    }
    public static Object getObject(String key){
        Jedis jedis = RedisConnection.getJedis();
        byte[] bytes = jedis.get(key.getBytes());
        jedis.close();
        return SerializeUtil.deserialize(bytes);
    }
}

User对象

public class User implements Serializable{
    private static final long serialVersionUID = -3210884885630038713L;
    private int id;
    private String name;
    public User(){
 
    }
    public User(int id,String name){
        this.id = id;
        this.name = name;
    }
    //setter和getter方法
}

测试

public class RedisTest {
 
    @Test
    public void testString(){
        RedisOps.set("user:1", "sisu");
        String user = RedisOps.get("user:1");
        Assert.assertEquals("sisu", user);
    }
 
    @Test
    public void testObject(){
        RedisOps.setObject("user:2",new User(2,"lumia"));
        User user = (User)RedisOps.getObject("user:2");
        Assert.assertEquals("lumia", user.getName());
    } 
}

二、将对象用FastJSON转为JSON字符串后存储

redis操作类

public class RedisOps {
    public static void setJsonString(String key,Object object){
        Jedis jedis = RedisConnection.getJedis();
        jedis.set(key, JSON.toJSONString(object));
        jedis.close();
    }
    public static Object getJsonObject(String key,Class clazz){
        Jedis jedis = RedisConnection.getJedis();
        String value = jedis.get(key);
        jedis.close();
        return JSON.parseObject(value,clazz);
    }
}

测试

@Test
    public void testObject2(){
        RedisOps.setJsonString("user:3", new User(3,"xiaoming"));
        User user = (User)RedisOps.getJsonObject("user:3",User.class);
        Assert.assertEquals("xiaoming", user.getName());
    }

三、将对象用Hash数据类型存储

redis操作类

public class RedisOps {
    public static void hSet(String key,String value){
        Jedis jedis = RedisConnection.getJedis();
        jedis.hSet(key, value);
        jedis.close();
    }
    public static String hGet(String key){
        Jedis jedis = RedisConnection.getJedis();
        String value = jedis.hGet(key);
        jedis.close();
        return value;
    }
}

测试

@Test
    public void testObject3(){
     //存
        RedisOps.hSet("user:3","id","3");
        RedisOps.hSet("user:3","name","xiaoming");
        
        //取
        String id =  RedisOps..hGet("user:3","id");
        String name = RedisOps.hGet("user:3","name");
        Assert.assertEquals("3", id);
        Assert.assertEquals("xiaoming", name);        
    }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Redis 相关文章推荐
Redis5之后版本的高可用集群搭建的实现
Apr 27 Redis
Redis Cluster 字段模糊匹配及删除
May 27 Redis
Redis性能监控的实现
Jul 09 Redis
厉害!这是Redis可视化工具最全的横向评测
Jul 15 Redis
Redis Cluster集群动态扩容的实现
Jul 15 Redis
Redis模仿手机验证码发送的实现示例
Nov 02 Redis
CentOS8.4安装Redis6.2.6的详细过程
Nov 20 Redis
聊聊redis-dump工具安装问题
Jan 18 Redis
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
Feb 12 Redis
Redis安装使用RedisJSON模块的方法
Mar 23 Redis
如何使用注解方式实现 Redis 分布式锁
Jul 23 Redis
Redis过期数据是否会被立马删除
Jul 23 Redis
springboot使用Redis作缓存使用入门教程
Jul 25 #Redis
Redis中一个String类型引发的惨案
缓存替换策略及应用(以Redis、InnoDB为例)
浅谈redis整数集为什么不能降级
嵌入式Redis服务器在Spring Boot测试中的使用教程
Jul 21 #Redis
Redis源码阅读:Redis字符串SDS详解
浅谈Redis位图(Bitmap)及Redis二进制中的问题
You might like
老机欣赏|中国60年代精品收音机
2021/03/02 无线电
PHP 命名空间实例说明
2011/01/27 PHP
PHP获取photoshop写入图片文字信息的方法
2015/03/31 PHP
Yii开启片段缓存的方法
2016/03/28 PHP
php解决和避免form表单重复提交的几种方法
2016/08/31 PHP
PHP面向对象多态性实现方法简单示例
2017/09/27 PHP
在 Laravel 6 中缓存数据库查询结果的方法
2019/12/11 PHP
利用JQuery和JS实现奇偶行背景颜色自定义效果
2012/11/19 Javascript
FF IE浏览器修改标签透明度的方法
2014/01/27 Javascript
js使用正则实现ReplaceAll全部替换的方法
2014/08/22 Javascript
jQuery实现炫酷的鼠标轨迹特效
2015/02/01 Javascript
Javascript优化技巧之短路表达式详细介绍
2015/03/27 Javascript
JavaScript实现跑马灯抽奖活动实例代码解析与优化(一)
2016/02/16 Javascript
Javascript中apply、call、bind的巧妙使用
2016/08/18 Javascript
原生js实现弹出层效果
2017/01/20 Javascript
vue中引用阿里字体图标的方法
2018/02/10 Javascript
nodejs基于express实现文件上传的方法
2018/03/19 NodeJs
微信小程序实现美团菜单
2018/06/06 Javascript
javascript使用substring实现的展开与收缩文字功能示例
2019/06/17 Javascript
js回溯法计算最佳旅行线路代码实例
2019/09/11 Javascript
node.js 微信开发之定时获取access_token
2020/02/07 Javascript
[02:05]DOTA2完美大师赛趣味视频之看我表演
2017/11/18 DOTA
python的文件操作方法汇总
2017/11/10 Python
python实现数据预处理之填充缺失值的示例
2017/12/22 Python
python计算两个矩形框重合百分比的实例
2018/11/07 Python
Python设计模式之职责链模式原理与用法实例分析
2019/01/11 Python
Python基于滑动平均思想实现缺失数据填充的方法
2019/02/21 Python
实例详解Matlab 与 Python 的区别
2019/04/26 Python
检测浏览器对HTML5和CSS3支持度的方法
2015/06/25 HTML / CSS
JOSEPH官网:英国奢侈时尚品牌
2018/01/31 全球购物
计算机专业毕业生的自我评价
2013/11/18 职场文书
争做文明公民倡议书
2014/08/29 职场文书
房屋租赁委托书范本
2014/10/04 职场文书
2014年信息技术工作总结
2014/12/16 职场文书
FP-growth算法发现频繁项集——构建FP树
2021/06/24 Python
MYSQL 表的全面总结
2021/11/11 MySQL