Jedis,SpringDataRedis

news2024/11/24 13:34:44

快速入门

导入依赖

        <!--jedis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.7.0</version>
        </dependency>
        <!--单元测试-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.7.0</version>
            <scope>test</scope>
        </dependency>

测试代码

package com.example;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;

public class JedisTest {
    private Jedis jedis;

    @BeforeEach
    void setUp() {
        jedis = new Jedis("192.168.168.168", 6379);
        jedis.auth("123456");
        jedis.select(0);
    }

    @Test
    void test() {
        String name = jedis.get("name");
        System.out.println(name);
    }

    @AfterEach
    void tearDown() {
        if(jedis != null){
            jedis.close();
        }
    }
}

jedis连接池

Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此推荐大家使用Jedis连接池代替Jedis的直连方式。

package com.example.utils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisConnectionFactory {
    private static JedisPool jedisPool;
    //在类加载时执行
    static {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(8);//最大连接数
        poolConfig.setMaxIdle(8);//最大空闲连接数
        poolConfig.setMinIdle(0);//最小空闲连接数
        poolConfig.setMaxWaitMillis(1000);//最大等待时间 (单位:毫秒)
        jedisPool = new JedisPool(poolConfig, "192.168.168.168", 6379, 1000, "123456");
    }//连接超时时间 1000毫秒
    public static Jedis getJedis() {
        return jedisPool.getResource();
    }
}

修改后这样获取jedis对象

    @BeforeEach
    void setUp() {
        jedis = JedisConnectionFactory.getJedis();
        jedis.auth("123456");
        jedis.select(0);
    }

SpringDataRedis

SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:Spring Data Redis

- 提供了对不同Redis客户端的整合(Lettuce和Jedis)
- 提供了RedisTemplate统一API来操作Redis
- 支持Redis的发布订阅模型
- 支持Redis哨兵和Redis集群
- 支持基于Lettuce的响应式编程
- 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化
- 支持基于Redis的JDKCollection实现

快速入门

导入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

配置redis

spring:
  data:
    redis:
      host: 192.168.168.168
      port: 6379
      password: 123456
      database: 0
      lettuce:
        pool:
          max-active: 8
          max-idle: 8
          min-idle: 0
          max-wait: 100ms

测试

package com.example;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;

@SpringBootTest
public class RedisTemplateTest {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void test01() {
        redisTemplate.opsForValue().set("name","lihua");
        System.out.println(redisTemplate.opsForValue().get("name"));
    }
}

自定义序列化

jdk序列化(默认的序列化方式)的问题

 进行如上测试后,发现并没有修改key为name的值为lihua,而是出现了这样的结果

原因如下

RedisTemplate可以接收任意Object作为值写入Redis:

只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的:


缺点:
- 可读性差
- 内存占用较大

***************************************************

自定义序列化方式为json序列化

首先写一个RedisTemplate的配置

package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

@Configuration
public class RedisTemplateConfig {
    @Bean
    //RedisConnectionFactory是spring内置的,在项目启动时会自动装配,因此作为参数传入即可
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        //创建RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        //设置连接工厂
        template.setConnectionFactory(factory);
        //创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        //设置key的序列化   RedisSerializer是redis的一个序列化器
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        //设置value的序列化
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(jsonRedisSerializer);
        //返回
        return template;
    }
}

在springboot项目启动时,这个bean就会被加载

重新测试

    @Test
    public void test01() {
        redisTemplate.opsForValue().set("name","zhaosi");
        System.out.println(redisTemplate.opsForValue().get("name"));
    }

测试结果如下

 

符合我们的预期

*********************************

也可以存入自定义对象

    @Test
    public void test02() {
        User u1 = new User(1, "laoda", 24);
        redisTemplate.opsForValue().set("user:001", u1);
    }
    @Test
    public void test03() {
        User user = (User) redisTemplate.opsForValue().get("user:001");
        System.out.println(user);
    }

测试结果如下

整体可读性有了很大提升,并且能将Java对象自动的序列化为JSON字符串,并且查询时能自动把JSON反序列化为Java对象。不过,其中记录了序列化时对应的class名称,目的是为了查询时实现自动反序列化。这会带来额外的内存开销。  (我们将用StringRedisTemplate进行改进)

SpringRedisTemplate 

为了节省内存空间,我们可以不使用JSON序列化器来处理value,而是统一使用String序列化器(这样value就不用存储对象的字节码文件了),要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。

因为存入和读取时的序列化及反序列化都是我们自己实现的,SpringDataRedis就不会将class信息写入Redis了。

这种用法比较普遍,因此SpringDataRedis就提供了RedisTemplate的子类:StringRedisTemplate,它的key和value的序列化方式默认就是String方式。

导入jackson依赖

        <!--Jackson依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

省去了我们自定义RedisTemplate的序列化方式的步骤,而是直接使用就好了

@SpringBootTest
public class StringRedisTemplateTest {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private static final ObjectMapper mapper = new ObjectMapper();

    @Test
    public void test() throws JsonProcessingException {
        User u1 = new User(2, "赵四", 25);
        //手动序列化
        String json = mapper.writeValueAsString(u1);
        System.out.println("序列化后的json字符串:"+json);
        //写入数据
        stringRedisTemplate.opsForValue().set("user:002",json);
        //获取数据
        String jsonUser = stringRedisTemplate.opsForValue().get("user:002");
        //反序列化
        User user = mapper.readValue(jsonUser, User.class);
        System.out.println("反序列化得到的结果:"+user);
    }
}

可以看到,里面是没有对象的字节码的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2122938.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SPI子系统

IO特性 SPI接口一般使用四条信号线通信&#xff1a; SDI&#xff08;数据输入&#xff09;&#xff0c;SDO&#xff08;数据输出&#xff09;&#xff0c;SCK&#xff08;时钟&#xff09;&#xff0c;CS&#xff08;片选&#xff09; MISO&#xff1a; 主设备输入/从设备输出…

每日刷题(二分)

E. Klees SUPER DUPER LARGE Array!!! https://codeforces.com/contest/2009/problem/E 思路&#xff1a; 题目让我们求从k开始的n个数的前k个数的和与剩下的数的和的差最小是多少&#xff0c;可以用数学思维O(1)求解&#xff0c;都是我数学比较差&#xff0c;我们这里用二分…

企业财税自动化解决方案的成本效益分析与投资回报预测

随着企业规模的扩大和业务复杂度的增加&#xff0c;企业在财务管理方面也面临着诸多挑战&#xff0c;传统的财务管理方式逐渐无法满足企业经营需求&#xff0c;借助财税自动化解决方案来提高财务效率和准确性、降低人力成本&#xff0c;为企业带来长期的效益提升&#xff0c;已…

基于MATLAB的图像融合设计

摘 要 图像融合能够将不同类型传感器获取的同一对象的图像数据进行空间配准。并且采用一定的算法将不同类型的传感器获取的同一对象的图像数据所含用的信息优势或互补性有机地结合起来产生的新的图像数据。这种新数据含有所研究对象的更多信息表征&#xff0c;与单一图像相对比…

《python语言程序设计》2018版第8章第15题商业:检测ISBN-10一个国际标准书号

这个作者一天净出幺蛾子.我这边还老打错字,我现在都不敢用缩写,都是全拼 str_vis_text "013601267" len_num len(str_vis_text)def run_text(num_t, text_about):text_sum 0for i in range(0, num_t):text_sum if_digit(text_about[i])*(i1)print(text_sum%11)pr…

Python框架Pandas:DataFrame的应用

一、DataFrame DataFrame是什么&#xff1f; 1.1 DataFrame的创建 1.1.1 方式一&#xff1a;使用字典加列表创建df&#xff0c;使用默认自增索引 import pandas as pd # 使用字典加列表创建df&#xff0c;使用默认自增索引 df1_data {日期:[2021-08-21,2021-08-22,2021-0…

应用连接错误,初始化mysql数据库恢复---惜分飞

有人在部署一个新网站的时候,写错了配置信息,直接导致原有数据库被清掉,并创建了新库和写入了数据(其实本质就是drop table恢复) 登录操作系统查看,发现数据库文件在根分区,创建了新库,写入了数据之外,还有几个G的binlog.全部恢复不太可能,最后客户决定需要恢复的2个核心表数…

如何将写好的Java代码打成jar包放在hadoops上运行

1、打包java文件 2、jar包上传&#xff0c;hadoop执行 我们将打好的jar包上传到Linux&#xff0c;因为hadoop是安装在Linux上的&#xff0c;然后用hadoop执行&#xff0c;执行前要确保已经在Linux上配置了hadoop的环境变量&#xff0c;不然就要到hadoop的目录下执行该命令 执…

记一次Hiveserver2连接异常的解决-腾讯云-emr

原文阅读&#xff1a;【巨人肩膀社区博客分享】记一次Hiveserver2连接异常的解决-腾讯云-emr 离线任务跑的好好的&#xff0c;忽然有一天失败了&#xff0c;查看海豚上的任务执行日志发现是hiveserver2连接超时了。 查看监控发现了几个问题一个是GC变得频繁&#xff0c;另一个…

Mac电脑剪切板在哪里找 苹果电脑剪切板打开教程【详解】

Windows 和 Mac 电脑在使用方式上存在一些差异&#xff0c;许多习惯了 Windows 系统的用户初次接触 Mac 时可能会对某些操作感到困惑。比如&#xff0c;很多人会问&#xff1a;Mac 上的剪贴板在哪里&#xff1f;如果你也有这样的疑问&#xff0c;不妨看看下面这篇关于如何在 Ma…

redis 基本数据类型—string类型

一、介绍 Redis 中的字符串&#xff0c;直接就是按照二进制数据的方式存储的&#xff0c;不会做任何的编码转换。 Redis对于 string 类型&#xff0c;限制了大小最大是512M 二、命令 SET 将 string 类型的 value 设置到 key 中。如果 key 之前存在&#xff0c;则覆盖&#…

系统架构设计师|关于系统架构-002

&#x1f4eb; 作者简介&#xff1a;「六月暴雪飞梨花」&#xff0c;专注于研究Java&#xff0c;就职于科技型公司后端工程师 &#x1f3c6; 近期荣誉&#xff1a;华为云云享专家、阿里云专家博主、腾讯云优秀创作者、腾讯云TDP-KOL、ACDU成员、墨天轮技术专家博主 &#x1f52…

DBeaver 24.2 发布下载,新增功能概览

DBeaver Ultimate Edtion 24.2 Multilingual (macOS, Linux, Windows) - 通用数据库工具 One tool for all data sources 请访问原文链接&#xff1a;https://sysin.org/blog/dbeaver/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sy…

【局域网投屏】sunshine和moonlight投屏/屏幕共享/扩展屏

主机是sunshine&#xff0c;客机是moonlight&#xff0c;一个太阳一个月光&#xff0c;两者真是太配啦&#xff01; 下载sunshine sunshine是服务器端&#xff0c;去以下GitHub链接下载windows端的解压缩即用版 https://github.com/LizardByte/Sunshine/releases下载完毕解压…

Linux高级查找、过滤

find 在指定目录下查找文件和目录 基本语法&#xff1a;find [路径] [ 参数] [查找条件] 常用参数 -name 根据文件或目录的名称查找 find /path -name test.txt-iname 与name类似&#xff0c;但忽略大小写-size 根据文件大小查找 find /path -size 10M-user 根据文…

HS光流法原理与实现

1. 前言 人眼观察到物体运动时,物体会在视网膜平面上形成一系列连续变化的图像“流过”视网膜,好像一种光的“流”,所以被称为光流。 光流基于像素点定义,所有光流的集合称为光流场。通过对光流场分析,可以得到物体相对于观察者的运动信息。计算光流场的方法有很多,常见的…

Java中的类型转换 Day4

类型转换 类型转换总结来说就是&#xff1a;自动提升 手动下降 3.1 自动类型转换 自动类型转换需要满足的要求 两种类型相互兼容 例&#xff1a;int类型的取值范围包含了short类型的取值范围 目标类型大于源类型 目标类型的取值范围&#xff08;等号左边&#xff09;大于源…

debug对于开发工程师很重要

在日常开发中&#xff0c;总会遇到一些出人意料的bug&#xff0c;程序跑飞&#xff0c;上电就挂&#xff0c;程序没有按预期执行诸如此类的问题&#xff0c;没有好的调试方法&#xff0c;真的很难定位问题&#xff0c;更别说解决了。在这里分享我用过的一些调试方法&#xff0c…

欧几里得算法求最大公约数

两个不全为0的非负整数m&#xff0c;n的最大公约数记为gcd&#xff08;m&#xff0c;n&#xff09;&#xff0c;代表能够整除&#xff08;即余数为0&#xff09;m和n的最大正整数。 计算gcd&#xff08;m&#xff0c;n&#xff09;的欧几里得算法&#xff1a; 第一步&#xf…

初识爬虫2

requests学习&#xff08;未更新完&#xff09;&#xff1a; 小技巧&#xff0c;如果你用的也是pycharm&#xff0c;对于控制台输出页面因为数据很长一行&#xff0c;不方便进行查看&#xff0c; 可以让它自动换行&#xff1a; 1.requests文档阅读学习链接&#xff1a;快速上…