【Redis学习笔记03】Java客户端

news2025/1/20 16:23:49

1. 初识Jedis

Jedis的官网地址:https://github.com/redis/jedis

1.1 快速入门

使用步骤
注意:如果是云服务器用户使用redis需要先配置防火墙!

  1. 引入maven依赖

    <dependencies>
        <!-- 引入Jedis依赖 -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>5.0.0</version>
        </dependency>
        <!-- 引入单元测试 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.10.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
  2. 建立连接

    @BeforeEach
    void setUp() {
        jedis = new Jedis("114.55.236.21:22", 6379);
        jedis.auth("123456");
        jedis.select(0);
    }
    
  3. 测试String类的方法

    @Test
    void testString() {
        // 1. 尝试set方法
        jedis.set("name", "wjj");
        // 2. 尝试get方法
        String name = jedis.get("name");
        System.out.println(name);
    }
    
  4. 释放连接

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

运行结果
image.png
image.png

2. 使用Jedis连接池

由于Jedis是线程不安全的,并且频繁创建销毁线程具有很大开销,因此我推荐使用连接池的方式使用Jedis
使用步骤

  1. 使用连接池创建连接工厂类

    /**
     * 基于连接池实现连接工厂类
     */
    public class JedisConnectionFactory {
        private static final JedisPool jedisPool;
    
        static {
            // 1. 创建连接池配置
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxTotal(8); // 最大连接数
            config.setMaxIdle(8); // 最大空闲连接数
            config.setMinIdle(0); // 最小空闲连接数
            config.setMaxWaitMillis(200); // 最长等待时间
            // 2. 创建JedisPool连接池
            jedisPool = new JedisPool(config, "114.55.236.21", 6379, 1000, "123456");
        }
    
        public static Jedis getConnection() {
            return jedisPool.getResource();
        }
    }
    
  2. 编写测试类测试Hash类型方法

    public class TestJedisPool {
        private Jedis jedis;
        @BeforeEach
        void setUp() {
            jedis = JedisConnectionFactory.getConnection();
        }
    
        @Test
        void testHash() {
            // 1. 使用hset方法
            jedis.hset("user:1", "name", "rice");
            jedis.hset("user:1", "age", "22");
            // 2. 使用hgetAll方法
            Map<String, String> map = jedis.hgetAll("user:1");
            System.out.println(map);
        }
    
        @AfterEach
        void tearDown() {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    
    

运行结果
image.png
image.png

2. 使用SpringBoot整合Redis

现在基于SpringBoot整合Redis已经成为企业的标配,其中SpringDataRedis就是专门用来操作Redis的集成模块,其具有以下特点:

  • 提供了对不同客户端的整合,比如Jedis和Lettuce
  • 提供了RedisTemplate统一API来操作Redis
  • 支持Redis的发布订阅模型
  • 支持Redis的哨兵和集群
  • 支持Lettuce的响应式编程
  • 支持基于JDK、JSON、String等对象的序列化和反序列化
  • 支持基于Redis的JDKCollection实现

2.1 SpringDataRedis快速入门

使用步骤:

  1. 引入maven依赖

    <!-- redis依赖 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!-- 连接池依赖 -->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
      <version>2.11.1</version>
    </dependency>
    
  2. application.yml中配置相关参数

    # 配置redis
    spring:
      data:
        redis:
          host: 114.55.236.21
          port: 6379
          password: 123456
          lettuce:
            pool:
              max-active: 8
              max-idle: 8
              min-idle: 0
              max-wait: 200
    

    由于Spring官方默认使用lettuce作为客户端,因此如果想要使用Jedis的配置,还需要引入Jedis的maven依赖

  3. 在测试类中自动装配RedisTemplate对象

    @Autowired
    private RedisTemplate redisTemplate;
    
  4. 创建测试类测试redisTemplate的使用

    @SpringBootTest
    class SpringDataRedisDemoApplicationTests {
    
    	@Resource
    	public RedisTemplate redisTemplate;
    
    	@Test
    	public void testString() {
    		System.out.println(redisTemplate);
    		// 1. 存入String类型数据
    		redisTemplate.opsForValue().set("id", "1");
    		// 2. 取出String类型数据
    		Object id = redisTemplate.opsForValue().get("id");
    		System.out.println(id);
    	}
    
    }
    

运行结果
image.png
image.png
但是我们发现其中插入了一个\xac\xed\x00\x05t\x00\x02id这样不知名的key,但是貌似是我们在代码中插入的key值id,但是怎么会以这样的方式呈现呢?
image.png
我们追溯源码可以发现RedisTemplate中使用默认的序列化器就是JDK序列化器,其接收Object类型参数并转换成字节数组存入Redis中,但是我们发现具有以下问题:

  1. 可读性差
  2. 内存占用较大

因此我们更加建议使用String类型序列化器作为keySerializer,而使用JSON序列化器作为valueSerializer

2.2 使用自定义序列化器

使用步骤

  1. 创建Redis配置类RedisConfig.java

    @Configuration
    public class RedisConfig {
    
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
            RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
            // 设置连接工厂
            redisTemplate.setConnectionFactory(connectionFactory);
            // 设置序列化工具
            GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
            // key和hashKey使用StringSerializer
            redisTemplate.setKeySerializer(RedisSerializer.string());
            redisTemplate.setHashKeySerializer(RedisSerializer.string());
            // value和hashValue使用GenericJackson2JsonRedisSerializer
            redisTemplate.setValueSerializer(jsonRedisSerializer);
            redisTemplate.setHashValueSerializer(jsonRedisSerializer);
            return redisTemplate;
        }
    }
    
  2. 编写测试类TestJsonSerializer.java

    @SpringBootTest
    public class TestJsonSerializer {
        @Autowired
        private RedisTemplate<String, Object> redisTemplate;
        @Test
        public void testJsonSerializer() {
            // 存放id
            redisTemplate.opsForValue().set("id", "2");
            // 取出id
            Object id = redisTemplate.opsForValue().get("id");
            System.out.println(id);
        }
    }
    

如果出现如下异常(莫慌,这是正常的!):
image.png
只要引入如下依赖即可:

<!-- 引入jackson-databind依赖 -->
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.14.1</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.14.1</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.14.1</version>
</dependency>

运行结果
image.png
image.png
此时可以发现id正常显示!
但是如果我们尝试将value设置为Java的对象,就会出现一定问题:
使用步骤

  1. 创建pojo包下的实体类User.java

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class User {
        private Integer id;
        private String name;
        private Integer age;
    }
    
  2. 在测试类中新增测试方法

    @Test
    public void testJsonObjectSerializer() {
        // 创建User类对象
        User user = new User(1, "zhangsan", 22);
        // 存放User对象
        redisTemplate.opsForValue().set("user:1", user);
        // 取出User对象
        User getUser = (User) redisTemplate.opsForValue().get("user:1");
        System.out.println(getUser);
    }
    

上述方法尝试将一个User类对象作为value,由于之前我们自定义了value的序列化器为JSON序列化器,因此其内部会自动进行序列化和反序列化
运行结果
image.png
image.png
我们需要重点关注其中的@class的字段内容,不难发现,RedisTemplate自动进行序列化和反序列化的依据就是利用Java的反射机制,因此需要保存类信息,但是这也引入了一个严重的问题:

  • 如果有上千万的数据量,每条信息都需要保存对应的类信息,会极大浪费内存空间!

因此我们还是建议使用手动序列化的方式进行存取!

2.3 手动序列化

使用步骤

  1. 引入JSON工具依赖

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.35</version>
    </dependency>
    
  2. 编写测试类手动序列化

    @Test
    public void testMyJSON() {
        // 1. 创建User对象
        User user = new User(2, "lisi", 22);
        // 2. 手动序列化为JSON格式数据
        String jsonString = JSONObject.toJSONString(user);
        redisTemplate.opsForValue().set("user:2", jsonString);
        // 3. 取出数据并手动序列化为User对象
        String userJSONString = (String) redisTemplate.opsForValue().get("user:2");
        User toUser = JSONObject.parseObject(userJSONString, User.class);
        System.out.println(toUser);
    }
    

运行结果
image.png
image.png
此时我们就实现了手动序列化的方式存储Java对象,一切大功告成!

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

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

相关文章

CSS 的圆角矩形

CSS 的圆角矩形 通过 border-radius 属性使矩形边框带圆角效果成为圆角矩形 语法&#xff1a;border-radius: length; length 是内切圆的半径&#xff0c;其数值越大, 弧线越明显 border-radius 属性值描述length定义圆角的形状%以百分比定义圆角的形状 生成圆形 让 border-…

英伟达狂飙,上演大象坐火箭

英伟达市值破 2W 亿 这两天全球资本市场最大的事情就是英伟达&#xff08;NVDA&#xff09;公布了财报。 本来市场&#xff08;分析师&#xff09;的预期就高&#xff0c;结果财报公布比预期还要高出不少。 NVDA 直接上演「大象坐火箭」&#xff0c;在财报公布后的第一个交易日…

Spring Cloud Gateway官方文档学习

文章目录 推荐写在前面一、熟悉Gateway基本概念与原理1、三大概念2、工作流程 二、基本使用路由断言的两种写法 三、路由断言工厂1、After路由断言工厂2、Before路由断言工厂3、Between路由断言工厂4、Cookie路由断言工厂5、Header路由断言工厂6、Host路由断言工厂7、Method路由…

[C++]18:set和map的使用

set和map的使用 一.关联式容器&#xff1a;1.简单概念&#xff1a;2.<key , value>--->键值对3.set和map的底层结构&#xff08;平衡搜索树或者红黑树&#xff09; 二.set1.set (排序不重复)1.模板参数&#xff1a;2.set是一个有序存储的容器&#xff1a;3.set中每个数…

STL常用容器(string容器)---C++

STL常用容器目录 1.string容器1.1 string基本概念1.2 string构造函数1.3 string赋值操作1.4 string字符串拼接1.5 string查找和替换1.6 string字符串比较1.7 string字符存取1.8 string插入和删除1.9 string子串 1.string容器 1.1 string基本概念 本质&#xff1a; string是C…

Peter算法小课堂—动态规划

Peter来啦&#xff0c;好久没有更新了呢 今天&#xff0c;我们来讨论讨论提高组的动态规划。 动态规划 动态规划有好多经典的题&#xff0c;有什么背包问题、正整数拆分、杨辉三角……但是&#xff0c;如果考到陌生的题&#xff0c;怎么办呢&#xff1f;比如说2000年提高组的…

计算机网络:思科实验【2-MAC地址、IP地址、ARP协议及总线型以太网的特性】

&#x1f308;个人主页&#xff1a;godspeed_lucip &#x1f525; 系列专栏&#xff1a;Cisco Packet Tracer实验 本文对应的实验报告源文件请关注微信公众号程序员刘同学&#xff0c;回复思科获取下载链接。 实验目的实验环境实验内容MAC地址、IP地址、ARP协议总线型以太网的…

渗透工具——kali中wpscan简介

一、什么是wpscan 1、常用于做用户名枚举爆破 2、WPScan是一个扫描 WordPress 漏洞的黑盒子扫描器&#xff0c;它可以为所有 Web 开发人员扫描 WordPress 漏洞并在他们开发前找到并解决问题。我们还使用了 Nikto &#xff0c;它是一款非常棒的Web 服务器评估工具&#xff0c;…

MySQL数据库调优之关联查询、排序查询、分页查询、子查询、Group by优化

关联查询优化 1.准备工作 CREATE TABLE IF NOT EXISTS type(id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,card INT(10) UNSIGNED NOT NULL,PRIMARY KEY(id));CREATE TABLE IF NOT EXISTS book( bookid INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, card INT(10) UNSIGNED N…

智慧应急与物联网相结合:物联网技术如何提升智慧应急响应能力

目录 一、引言 二、智慧应急与物联网技术的结合 三、物联网技术提升智慧应急响应能力的途径 四、物联网技术在智慧应急中的应用案例 五、物联网技术在智慧应急中面临的挑战与解决方案 挑战一&#xff1a;技术标准与规范不统一 解决方案&#xff1a; 挑战二&#xff1a;…

【考研数学】基础阶段习题1800和660怎么选❓

我建议以1800题为主 1800题包含基础和强化两部分&#xff0c;基础部分题量很大&#xff0c;类型也很全面&#xff0c;并且难度一点也不高&#xff0c;适合基础不好的学生来做。 660题难度比较大&#xff0c;不适合基础阶段做。 660题虽然名字叫基础训练&#xff0c;但是不适…

英语连读技巧15

1. first one – 第一个 连读听起来就像是&#xff1a;【佛斯湾】 连读的音标为&#xff1a; 例句&#xff1a;I don’t want to be the first one there agin. 发音指导&#xff1a;在“first one”的连读中&#xff0c;"t"和"o"之间的连接几乎消失&a…

Java线程池实现原理详解

线程池是什么 线程池&#xff08;Thread Pool&#xff09;是一种基于池化思想管理线程的工具&#xff0c;经常出现在多线程服务器中&#xff0c;如MySQL。 线程过多会带来额外的开销&#xff0c;其中包括创建销毁线程的开销、调度线程的开销等等&#xff0c;同时也降低了计算…

03|Order by与Group by优化

索引顺序依次是 &#xff1a; name,age,position 案例1 EXPLAIN SELECT * FROM employees WHERE name LiLei AND position dev ORDER BY age;分析: 联合索引中只是用到了name字段做等值查询[通过key_len 74可以看出因为name字段的len74]&#xff0c;在这个基础上使用了age进…

sql-labs32关宽字节注入

一、环境 网上有自己找很快 二、如何通关 2.1解释 虚假预编译没有参数绑定的过程&#xff0c;真实预编译有参数绑定的过程 宽字节注入出现的本质就是因为数据库的编码与代码的编码不同&#xff0c;导致用户可以通过输入精心构造的数据通过编码转换吞掉转义字符。 在32关中…

华为HCIP Datacom H12-831 卷24

多选题 1、如图所示&#xff0c;某园区部署OSPF实现网络互通&#xff0c;其中Area1部署为NSSA区域。某工程师为了实现R1访问R4的环回口地址&#xff0c;在R4的OSPF进程中引入直连路由。以下关于该场景的描述,错误的有哪些项? A、在R4引入直连路由后&#xff0c;R1通过转换后的…

Java基于物联网技术的智慧工地云管理平台源码 依托丰富的设备接口标准库,快速接入工地现场各类型设备

目录 风险感知全面化 项目进度清晰化 环境监测实时化 人员管理高效化 工地数字化 数据网络化 管理智慧化 智慧工地平台整体架构 1个可扩展监管平台 2个应用端 3方数据融合 N个智能设备 智慧工地的远程监管&#xff0c;是工地负责人掌握施工现场情况的必要手段&…

第6.4章:StarRocks查询加速——Colocation Join

目录 一、StarRocks数据划分 1.1 分区 1.2 分桶 二、Colocation Join实现原理 2.1 Colocate Join概述 2.2 Colocate Join实现原理 三、应用案例 注&#xff1a;本篇文章阐述的是StarRocks-3.2版本的Colocation Join 官网文章地址&#xff1a; Colocate Join | StarRoc…

JAVA算法和数据结构

一、Arrays类 1.1 Arrays基本使用 我们先认识一下Arrays是干什么用的&#xff0c;Arrays是操作数组的工具类&#xff0c;它可以很方便的对数组中的元素进行遍历、拷贝、排序等操作。 下面我们用代码来演示一下&#xff1a;遍历、拷贝、排序等操作。需要用到的方法如下 public…

SpringMVC 学习(五)之域对象

目录 1 域对象介绍 2 向 request 域对象共享数据 2.1 通过 ServletAPI (HttpServletRequest) 向 request 域对象共享数据 2.2 通过 ModelAndView 向 request 域对象共享数据 2.3 通过 Model 向 request 域对象共享数据 2.4 通过 map 向 request 域对象共享数据 2.5 通过…