作者 | 桌前明月

来源 | CSDN博客

头图 | 付费下载自视觉中国

出品 | CSDN(ID:CSDNnews)

前言

提到Redis 大部分的人首先想到的可能就是缓存,那么在 Java 项目中如何把对象缓存起来呢?这就是本文接下来要介绍的内容:缓存对象。本文通过SpringBoot 项目带你快速了解通过Jedis 把对象缓存到Redis中。

阅读本文需要你了解如何搭建 SpringBoot 项目即可,另外需要了解的是本文SpringBoot 版本是 2.1.0.RELEASE。关于SpringBoot 集成 Jedis 请参考:玩转 SpringBoot 2.x 之 快速集成 Jedis客户端(普通版)

接下来就让我们开始具体的代码案例介绍吧!

代码案例

演示通过将下面的 User 类创建的对象缓存到 Redis 中,具体有2种方式:序列化、Json。User 类具体代码如下:

 1public class User implements Serializable {23    private String name;4    private Integer age;56    public User(String name,Integer age){7        this.name = name;8        this.age = age;9    }
10    //省略 getter and setter 方法
11}

关于 过期时间处理和返回Jedis 线程操作到线程池操作封装到了 JedisCacheServiceSupport 中,具体代码如下:

 1public abstract class JedisCacheServiceSupport {2    public static final long EXPIRE_MILLISECONDS_DEFAULT_LONG = 3*60*60*1000;34    public Long getExpireTime(Long expireTime) {5        expireTime = (expireTime == null || expireTime.longValue() <= 0) ? EXPIRE_MILLISECONDS_DEFAULT_LONG : expireTime;6        return expireTime;7    }89    public void close(Jedis jedis){
10        if(jedis != null){
11            jedis.close();
12        }
13    }
14}

序列化方式

序列化的方式通过现将对象转换成二进制的流(序列化)后保存到 Redis 中,然后通过key 获取到二进制,在把二进制流转换成对象(反序列化)。

保存对象的具体操作如下:

通过 ObjectOutputStream.writeObject(object) 将User 对象转换成byte 数组,然后通过 psetex(byte[] key, long milliseconds, byte[] value) 将 byte[] 数组存入Redis中。其中

  • byte[] key:需要将key 转换成byte数组。
  • long milliseconds:是对象在Redis 中存活的时间,以毫秒为单位。
  • byte[] value:对象转换成的btye 数组。

获取对象的具体操作如下:

通过 get(byte[] key) 获取 User 对象转换的byte 数组,然后通过 ObjectInputStream.readObject() 将数组转换成User对象。

通过序列化方式保存和获取对象具体代码如下:

  1@Service2public class JedisCacheService extends JedisCacheServiceSupport  {34    private static Logger logger = LoggerFactory.getLogger(JedisCacheService.class);5678    @Autowired9    private JedisPool jedisPool;1011    /**12     * 获取缓存中的对象13     * @param key14     * @return15     */16    public Object getObject(String key) {17        Jedis jedis = null;18        Object object = null;19        try {20            jedis = jedisPool.getResource();21            byte[] ObjectByteArray = jedis.get(key.getBytes());22            object = unserialize(ObjectByteArray);23        }catch (Exception e){24            e.printStackTrace();25        }finally {26            close(jedis);27        }28        return object;29    }3031    /**32     *  将对象缓存到Redis中,设置默认过期时间33     * @param key34     * @param value35     */36    public void putObject(String key, Object value) {37        putObject(key,value,null);38    }39    /**40     *  将对象缓存到Redis中,自定义认过期时间41     * @param key42     * @param value43     */44    public void putObject(String key, Object value, Long expireTime) {45        Jedis jedis = null;46        try {47            jedis = jedisPool.getResource();48            jedis.psetex(key.getBytes(),getExpireTime(expireTime),serialize(value));49        }catch (Exception e){50            e.printStackTrace();51        }finally {52            close(jedis);53        }54    }555657    /**58     * 序列化59     * @param object60     * @return61     */62    public static byte[] serialize(Object object) {63        ObjectOutputStream oos = null;64        ByteArrayOutputStream baos = null;65        try {66            baos = new ByteArrayOutputStream();67            oos = new ObjectOutputStream(baos);68            oos.writeObject(object);69            byte[] bytes = baos.toByteArray();70            return bytes;71        } catch (Exception e) {72            logger.error(e.getMessage(), e);73        } finally {74            IOUtil.closeStream(oos);75            IOUtil.closeStream(baos);76        }77        return null;78    }7980    /**81     * 反序列化82     * @param bytes83     * @return84     */85    public static Object unserialize(byte[] bytes) {86        if (bytes == null) return null;8788        ByteArrayInputStream bais = null;89        ObjectInputStream ois = null;90        try {91            bais = new ByteArrayInputStream(bytes);92            ois = new ObjectInputStream(bais);93            return ois.readObject();94        } catch (Exception e) {95            logger.error(e.getMessage(), e);96        } finally {97            IOUtil.closeStream(bais);98            IOUtil.closeStream(ois);99        }
100        return null;
101    }
102}

关闭 输入流和输出流工具类具体代码如下:

 1public class IOUtil {2    public static void closeStream(InputStream inputStream) {3        if (inputStream != null) {4            try {5                inputStream.close();6            } catch (IOException e) {7                e.printStackTrace();8            }9
10        }
11    }
12
13    public static void closeStream(OutputStream outputStream) {
14        if (outputStream != null) {
15            try {
16                outputStream.close();
17            } catch (IOException e) {
18                e.printStackTrace();
19            }
20
21        }
22    }
23}

序列化方式演示

测试 JedisCacheService putObject(将对象放入缓存中)、getObject(从缓存中获取对象),具体代码如下:

 1@RunWith(SpringRunner.class)2@SpringBootTest3public class JedisCacheServiceTest {4    private  Logger logger = LoggerFactory.getLogger(JedisCacheService.class);5    @Autowired6    private JedisCacheService jedisCacheService;78    @Test9    public void putObject() {
10        User user = new User("zhuoqiammingyue",19);
11        jedisCacheService.putObject("user01",user);
12        logger.info("缓存用户成功!");
13    }
14
15    @Test
16    public void getObject() {
17        User user = (User)jedisCacheService.getObject("user01");
18        logger.info("User name={},age={}",user.getName(),user.getAge());
19    }
20}

putObject 日志信息:

12020-02-26 22:08:50.320  INFO 26748 --- [           main] cn.lijunkui.cache.JedisCacheServiceTest  : Started JedisCacheServiceTest in 7.157 seconds (JVM running for 9.357)
22020-02-26 22:08:51.144  INFO 26748 --- [           main] cn.lijunkui.cache.JedisCacheService      : 缓存用户成功!

getObject 日志信息:

12020-02-26 22:09:57.492  INFO 9612 --- [           main] cn.lijunkui.cache.JedisCacheServiceTest  : Started JedisCacheServiceTest in 7.07 seconds (JVM running for 8.902)
22020-02-26 22:09:58.143  INFO 9612 --- [           main] cn.lijunkui.cache.JedisCacheService      : User name=zhuoqiammingyue,age=19

Json 方式

Json 的方式是将对象转换成可阅读的Json 串后保存到 Redis 中,然后通过key 获取到Json 串,在把Json 串成对象。对象转成成Json串是通过谷歌的Gson 完成的,所以需要引入Gson的依赖,具体依赖代码如下:

1<dependency>
2    <groupId>com.google.code.gson</groupId>
3    <artifactId>gson</artifactId>
4    <version>2.8.5</version>
5</dependency>

Json 保存对象的具体操作如下:

通过 Gson.toJson(Object src) 将User 对象转换成 Json串,然后通过 psetex(String key, long milliseconds, String value) 将 Json串存入Redis中。

Json 获取对象的具体操作如下:

通过 get(String key) 获取 User 对象的Json串,然后通过 Gson.fromJson(String json, Class<T> classOfT) 将Json串转换成User对象。

通过Json 方式保存和获取对象具体代码如下:

 1@Service2public class JedisJsonCacheService extends JedisCacheServiceSupport {34    private static Logger logger = LoggerFactory.getLogger(JedisJsonCacheService.class);56    @Autowired7    private JedisPool jedisPool;89    /**
10     * 获取缓存中的对象
11     * @param key
12     * @param clazz
13     * @return
14     */
15    public Object getObject(String key,Class clazz) {
16        Jedis jedis = null;
17        Object object = null;
18        try {
19            jedis = jedisPool.getResource();
20            String objectJson = jedis.get(key);
21             object = toObjce(objectJson,clazz);
22        }catch (Exception e){
23            e.printStackTrace();
24        }finally {
25            close(jedis);
26        }
27        return object;
28    }
29
30    /**
31     * 将对象缓存到Redis中,设置默认过期时间
32     * @param key
33     * @param value
34     */
35    public void putObject(String key, Object value) {
36        putObject(key, value,null);
37    }
38
39    /**
40     * 将对象缓存到Redis中,自定义认过期时间
41     * @param key
42     * @param value
43     * @param expireTime
44     */
45    public void putObject(String key, Object value, Long expireTime) {
46        Jedis jedis = null;
47        try {
48            jedis = jedisPool.getResource();
49            jedis.psetex(key,getExpireTime(expireTime),toJson(value));
50        }catch (Exception e){
51            e.printStackTrace();
52        }finally {
53            close(jedis);
54        }
55    }
56
57
58
59    /**
60     * 将对象转换成Json串
61     * @param value
62     * @return
63     */
64    private String toJson(Object value) {
65        Gson gson = new Gson();
66        return gson.toJson(value);
67    }
68
69    /**
70     * 将Json串转换成对象
71     * @param json
72     * @param clazz
73     * @return
74     */
75    private Object  toObjce(String json,Class clazz) {
76        Gson gson = new Gson();
77        return gson.fromJson(json,clazz);
78    }
79}

序列化方式演示

测试 JedisJsonCacheServiceTest putObject(将对象放入缓存中)、getObject(从缓存中获取对象),具体代码如下:

 1@RunWith(SpringRunner.class)2@SpringBootTest3public class JedisJsonCacheServiceTest {45    private Logger logger = LoggerFactory.getLogger(JedisJsonCacheServiceTest.class);6    @Autowired7    private JedisJsonCacheService jedisJsonCacheService;89    @Test
10    public void putObject() {
11        User user = new User("zhuoqiammingyue2",20);
12        jedisJsonCacheService.putObject("user02",user);
13        logger.info("缓存用户成功!");
14    }
15
16    @Test
17    public void getObject() {
18        User user = (User)jedisJsonCacheService.getObject("user02",User.class);
19        logger.info("User name={},age={}",user.getName(),user.getAge());
20    }
21}

putObject 日志信息:

12020-02-27 07:57:16.184  INFO 3692 --- [           main] c.l.cache.JedisJsonCacheServiceTest      : Started JedisJsonCacheServiceTest in 7.92 seconds (JVM running for 10.786)
22020-02-27 07:57:16.852  INFO 3692 --- [           main] c.l.cache.JedisJsonCacheServiceTest      : 缓存用户成功!

getObject 日志信息:

12020-02-27 07:57:56.359  INFO 27624 --- [           main] c.l.cache.JedisJsonCacheServiceTest      : Started JedisJsonCacheServiceTest in 7.364 seconds (JVM running for 9.256)
22020-02-27 07:57:56.824  INFO 27624 --- [           main] c.l.cache.JedisJsonCacheServiceTest      : User name=zhuoqiammingyue2,age=20

小结

序列化和Json这2种方式,在实际开发中可以根据你的喜好自行选择。Json 方式使用的是Gson 当然你也可以使用 FastJson ,序列化采用了 Java 原生的序列化和反序列化,同时你也可以切换成效率更高的 Hessian 进行序列化和反序列化。

代码示例

我本地环境如下:

  • SpringBoot Version: 2.1.0.RELEASE
  • Apache Maven Version:3.6.0
  • Java Version:1.8.0_144
  • IDEA:IntellJ IDEA

操作过程如出现问题可以在我的GitHub 仓库 springbootexamples 中模块名为 spring-boot-2.x-redis-jedis-objectcache 项目中进行对比查看

GitHub:https://github.com/zhuoqianmingyue/springbootexamples

原文链接:https://blog.csdn.net/ljk126wy/article/details/104519059

获取对象的key_玩转 SpringBoot2.x 之缓存对象相关推荐

  1. 玩转SpringBoot2.x之缓存对象

    前言 提到Redis 大部分的人首先想到的可能就是缓存,那么在 Java 项目中如何把对象缓存起来呢?这就是本文接下来要介绍的内容:缓存对象.本文通过SpringBoot 项目带你快速了解通过Jedi ...

  2. 玩转 SpringBoot2.x 之缓存对象 | 原力计划

    作者 | 桌前明月 来源 | CSDN博客 头图 | 付费下载自视觉中国 出品 | CSDN(ID:CSDNnews) 前言 提到Redis 大部分的人首先想到的可能就是缓存,那么在 Java 项目中 ...

  3. 深入理解:顶点缓存对象(VBO)

    深入理解:顶点缓存对象(VBO) 顶点缓存对象(VBO) 深入理解:顶点缓存对象(VBO) 前言 一.创建VBO 二.绘制VBO 更新VBO 实例 源码下载 引用 前言 GL_ARB_vertex_b ...

  4. 玩转springboot2.x 通过druid-spring-boot-starter整合Druid(Mybatis版)

    在阅读前这篇博客之前请先异步 玩转springboot2.x整合mybatis因为我们这篇博客是在其基础之上进行讲解的. Druid是什么? Druid是Java语言中最好的数据库连接池.Druid能 ...

  5. 利用python获取指定url在ATS中缓存对象的信息

    业务需求 给定url,如何查询指定的ATS中是否有该url的缓存对象信息?如果缓存了的话,希望提供该缓存对象的大小,缓存时间,缓存文件名,缓存份数(document alternative)等等信息 ...

  6. 玩转springboot2.x之异步调用@Async

    专题系列分类:玩转SpringBoot2.x系列教程 我们在正常开发中一般都是通过同步的方式进行处理的,但是有时候执行多个任务并不是都需要一起执行完才行,采取异步的方式可以有效提升一个请求响应的时间. ...

  7. 玩转springboot2.x之自定义项目内自动配置

    专题系列分类:玩转SpringBoot2.x系列教程 SpringBoot 为我们提供自动配置相关操作,SpringBoot 大量starter依赖就是通过自动配置来实现的.我在上一篇博客 玩转spr ...

  8. 玩转 SpringBoot2.x 之自定义配置类整合Druid(Mybatis版)

    专题系列分类:玩转SpringBoot2.x系列教程 前言 在阅读前这篇博客之前请先移步 玩转 SpringBoot 2.x 整合 Mybatis因为我们这篇博客是在其基础之上进行讲解的.在玩转 Sp ...

  9. 获取两个List集合中的不相同的对象

    import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;/* ...

最新文章

  1. python中csv文件操作_python中操作csv文件
  2. IOS网络编程之http请求响应篇
  3. HDU 5861 Road 线段树区间更新单点查询
  4. SAP库存解析(MC.9)
  5. Core Dump解析(1)
  6. python丢失api-ms-win-crt-process_api-ms-win-crt-process-l1-1-0.dll 丢失的处理,遇到问题和完美解决...
  7. 浅谈jQuery中 wrap() wrapAll() 与 wrapInner()的差异
  8. java 合并流(SequenceInputStream)
  9. iOS 16要来了:速度更快、UI改动明显?苹果WWDC大会或将在线下举行
  10. 从还珠格格到街头霸王!80后的怀旧神器 三星GalaxyFold另类体验
  11. 线性表:4.结合顺序表和链表——静态链表及C语言实现
  12. Java并发之线程池ThreadPoolExecutor源码分析学习
  13. 常用的 iptables配置脚本
  14. 树莓派做无线打印服务器,用树莓派和 CUPS 打印服务器将你的打印机变成网络打印机...
  15. api 二次 开发 禅道_二次开发机制 - 禅道开源版使用帮助 - 禅道开源项目管理软件...
  16. 柳传志:选人要看“后脑勺”
  17. matlab整流仿真,整流电路MATLAB仿真实验 - 范文中心
  18. 大数据教程(10.5)运营商流量日志解析增强
  19. 有关“SRS Audio Sandbox”的一些问题?
  20. 去除ubuntu u盘只读的解决办法

热门文章

  1. Win7+keras+tensorflow使用YOLO-v3训练自己的数据集
  2. 关于【AC自动姬】的学习
  3. 2015 EC L - Multiplication Table
  4. 饿了么订单--快到碗里来
  5. deferred对象
  6. CCNA基础(一):交换机和路由器基础配置
  7. CISA 已遭利用漏洞列表新增17项
  8. KindleDrip:从邮件地址到信用卡盗刷的严重漏洞,值$1.8万奖金
  9. 微软补丁星期二修复120个漏洞,含2个已遭利用的 0day
  10. lightOJ 1132 Summing up Powers(矩阵 二分)