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 相关文章推荐
浅谈redis五大数据结构和使用场景
Apr 12 Redis
Redis遍历所有key的两个命令(KEYS 和 SCAN)
Apr 12 Redis
详解Redis实现限流的三种方式
Apr 27 Redis
redis通过6379端口无法连接服务器(redis-server.exe闪退)
May 08 Redis
Redis数据结构之链表与字典的使用
May 11 Redis
浅谈Redis主从复制以及主从复制原理
May 29 Redis
Redis主从配置和底层实现原理解析(实战记录)
Jun 30 Redis
在redisCluster中模糊获取key方式
Jul 09 Redis
redis数据结构之压缩列表
Mar 21 Redis
redis 解决库存并发问题实现数量控制
Apr 08 Redis
Redis基本数据类型String常用操作命令
Jun 01 Redis
利用Redis实现点赞功能的示例代码
Jun 28 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
让CodeIgniter的ellipsize()支持中文截断的方法
2014/06/12 PHP
ThinkPHP查询中的魔术方法简述
2014/06/25 PHP
Yii2简单实现给表单添加验证码的方法
2016/07/18 PHP
IE/FireFox具备兼容性的拖动代码
2007/08/13 Javascript
JavaScript 加号(+)运算符号
2009/12/06 Javascript
MC Dialog js弹出层 完美兼容多浏览器(5.6更新)
2010/05/06 Javascript
js substring从右边获取指定长度字符串(示例代码)
2013/12/23 Javascript
JavaScript判断表单提交时哪个radio按钮被选中的方法
2015/03/21 Javascript
JQuery选中checkbox方法代码实例(全选、反选、全不选)
2015/04/27 Javascript
javaScript数组迭代方法详解
2016/04/14 Javascript
Javascript 闭包详解及实例代码
2016/11/30 Javascript
基于Bootstrap的网页设计实例
2017/03/01 Javascript
详解Node.js利用node-git-server快速搭建git服务器
2017/09/27 Javascript
JavaScript实现求最大公共子串的方法
2018/02/03 Javascript
vue3.0 CLI - 2.2 - 组件 home.vue 的初步改造
2018/09/14 Javascript
vue中的过滤器实例代码详解
2019/06/06 Javascript
使用Bootstrap做一个朝代历史表
2019/12/10 Javascript
[30:00]完美世界DOTA2联赛PWL S2 Rebirth vs LBZS 第二场 11.28
2020/12/01 DOTA
[54:58]完美世界DOTA2联赛PWL S2 LBZS vs Rebirth 第一场 11.25
2020/11/25 DOTA
Python中的默认参数详解
2015/06/24 Python
Python实现识别手写数字 简易图片存储管理系统
2018/01/29 Python
PyQt5+requests实现车票查询工具
2019/01/21 Python
python 实现返回一个列表中出现次数最多的元素方法
2019/06/11 Python
处理Selenium3+python3定位鼠标悬停才显示的元素
2019/07/31 Python
Python List列表对象内置方法实例详解
2019/10/22 Python
Python使用pycharm导入pymysql教程
2020/09/16 Python
python日志通过不同的等级打印不同的颜色(示例代码)
2021/01/13 Python
socket.io 和canvas 实现的共享画板功能
2019/05/22 HTML / CSS
乐天旅游台湾网站:Rakuten Travel TW
2017/06/01 全球购物
澳大利亚最超值的自行车之家:Reid Cycles
2019/03/24 全球购物
STP的判定过程
2012/10/01 面试题
C#如何调用Windows程序打开一个文档
2014/12/26 面试题
法律工作求职自荐信
2013/10/31 职场文书
幼儿园欢迎词范文
2015/01/26 职场文书
遗嘱范文
2015/08/07 职场文书
JAVA springCloud项目搭建流程
2022/05/11 Java/Android