【开发篇】七、RedisTemplate与StringRedisTemplate + Jedis与Lettcus

news2024/12/23 12:25:44

文章目录

  • 1、RedisTemplate详解
  • 2、常用方法
  • 3、关于IDEA的报黄
  • 4、RedisTemplate和StringRedisTemplate的区别
  • 5、如何通用RedisTemplate和StringRedisTemplate
  • 6、Jedis
  • 7、Jedis的连接池
  • 8、封装Jedis工具类
  • 8、RedisTemplate底层实现技术切换

在这里插入图片描述

1、RedisTemplate详解

RedisTemplate是Spring Data Redis提供的一个用于与Redis交互的高级工具类。它封装了与Redis服务器通信的底层细节,并提供了许多方便的方法来操作Redis的各种数据结构。

  • RedisTemplate基于Jedis或Lettuce等连接池技术,实现了与Redis服务器的连接和资源管理
  • 类中定义了一系列方法,可处理Redis的各种数据结构和执行各种Redis命令
  • RedisTemplate内部使用序列化器将Java对象转换为字节数组,并将其存储到Redis中。同时,还负责将从Redis中获取的字节数组转换回Java对象
//关于K,V
@Autowired
RedisTemplate<K,V> redisTemplate;

当使用RedisTemplate操作Redis时,K的类型通常是String类型,即键的数据类型为字符串。而V的类型可以是任意类型,取决于你存储的实际数据。RedisTemplate支持多种数据结构,例如字符串、哈希、列表、集合、有序集合等,因此V的类型可以是String、Hash、List、Set、ZSet等,RedisTemplate提供操作各种数据存储类型的接口API,不同类型调用不同方法:

在这里插入图片描述

2、常用方法

存取不同类型的value数据,调用方法获取不同类型的操作对象:

#1opsForValue()

返回一个用于操作String类型的ValueOperations对象,可以对Redis中的字符串键值对进行操作

#2opsForHash()

返回一个用于操作Hash类型的HashOperations对象,可以对Redis中的哈希数据结构进行操作

#3opsForList()

返回一个用于操作List类型的ListOperations对象,可以对Redis中的列表数据结构进行操作

#4opsForSet()

返回一个用于操作Set类型的SetOperations对象,可以对Redis中的集合数据结构进行操作

#5opsForZSet()

返回一个用于操作Sorted Set类型的ZSetOperations对象,可以对Redis中的有序集合数据结构进行操作


#6execute(RedisCallback)

用于执行自定义的Redis操作,可以通过实现RedisCallback接口来自定义要执行的操作

当你调用RedisTemplate的opsForValue()方法时,返回的实例可以用于操作字符串值;调用opsForHash()方法时,可以操作哈希类型的值;调用opsForList()方法时,可以操作列表类型的值;

总之就是,要操作什么类型的Redis数据,就调opsForxxx()方法获取什么类型的Operations对象,完了用这个对象调用set、get、hget等方法就行。

3、关于IDEA的报黄

在这里插入图片描述

4、RedisTemplate和StringRedisTemplate的区别

二者都是Spring封装好的操作操作Redis的工具对象,从源码来看为:

public class StringRedisTemplate extends RedisTemplate<String,String> {
	//.....
}

即:

  • 两者的关系是StringRedisTemplate继承RedisTemplate

  • RedisTemplate以对象作为key和value,内部对数据进行序列化

  • StringRedisTemplate以字符串作为key和value,与Redis客户端操作等效

  • 存取数据时,序列化的方式不同,互相查不到对方写进来的数据,导致了二者只能各自管各自的数据,给人一种它们数据不互通的感觉,但其实是同一个redis库

  • SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略

详细说就是:

  • RedisTemplate使用的是JdkSerializationRedisSerializer存入数据,会将数据先序列化成字节数组,然后在存入Redis数据库
  • 如果数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,那选择RedisTemplate最优

所以,我们看到redisTemplate对象存进去的数据在客户端长这样:
在这里插入图片描述

此时就有个问题,我们用RedisTemplate从Redis里get查数据时,也是默认将数据当作字节数组来转成对象或可读字符串。那如果redis里存的key本身就是可读的字符串,再当字节数组来转换就会获取不到数据,由此,StringRedisTemplate出现

StringRedisTemplate使用的是StringRedisSerializer,当你的redis数据库里面本来存的是字符串数据,或者你要存取的数据就是字符串类型数据的时候,那么你就使用StringRedisTemplate即可。

当redis中存入的数据是可读形式而非字节数组时,使用redisTemplate取值的时候会无法获取导出数据,获得的值为null,此时就可以使用 StringRedisTemplate 试试,同理,使用RedisTemplate来set进去的数据,用StringRedisTemplate也无法获取。

5、如何通用RedisTemplate和StringRedisTemplate

二者存取的差异在于key和value的序列化处理类,想实现混用redisTemplate和stringRedisTemplate,就得指定统一的key和Value的序列化处理类,如,让RedisTemplate序列化时,使用StringRedisTemplate的StringRedisSerializer。

//示例,这块在旧项目里应该是祖传的,新项目的话借鉴下若依框架吧
@Configuration
public class RedisConfig{
	@Bean
	public RedisTemplate<Object, Object> redisSessionTemplate(RedisConnectionFactory factory) {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		// 配置连接工厂
		template.setConnectionFactory(factory);
		//JdkSerializationRedisSerializer jdkRedisSerializer = new JdkSerializationRedisSerializer();
		RedisSerializer<String> keySerializer = new StringRedisSerializer();
		RedisSerializer<Object> valueSerializer = new JdkSerializationRedisSerializer(this.getClass().getClassLoader());
		// 值采用json序列化
		template.setValueSerializer(valueSerializer);
		//使用StringRedisSerializer来序列化和反序列化redis的key值
		template.setKeySerializer(keySerializer);
		// 设置hash key 和value序列化模式
		template.setHashKeySerializer(keySerializer);
		template.setHashValueSerializer(valueSerializer);
		template.afterPropertiesSet();
		return template;
	}
}

6、Jedis

  • Jedis就是Redis官方推荐的Java连接开发工具。

  • 在Java中,Redis对应于Jedis就相当于关系数据库对应于JDBC!!!

使用实例,首先引入依赖:

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

对于不用认证的redis,直接new一个Jedis对象,调用与指令名相同的API来完成数据操作即可:

// 第一个参数是Redis的IP地址,第二个参数是Redis的端口号
Jedis jedis = new Jedis("localhost", 6379);
// 写
jedis.set("msg", "Hello World!");
//查
String msg = jedis.get("msg");	
// 打印Hello World
System.out.println(msg);	
// 关闭Redis连接
jedis.close();

有认证的则:

Jedis jedis = new Jedis("localhost", 6379);

jedis.auth("password");

//auth方法重载
jedis.auth("username","password");

或者借助JedisShardInfo对象:

JedisShardInfo info = new JedisShardInfo("localhost",6379);

info.setPassword("admin123");

Jedis jedis  = new Jedis(info);

jedis.get("xxx")

7、Jedis的连接池

Jedis提供了连接池机制,需要操作Redis数据时,向Jedis连接池获取Redis的连接对象即可(类比JDBC的Connection对象),Jedis的连接池类为redis.clients.jedis.JedisPool。

// 初始化连接池类(使用默认连接池参数)
//JedisPool构造方法重载,你再传用户名密码也行
JedisPool jp = new JedisPool("localhost", 6379);

// 获取一个Jedis连接
Jedis jedis = jp.getResource();

也可使用配置类JedisPoolConfig来指定连接池的其他参数:

JedisPoolConfig jpc = new JedisPoolConfig();

// 设置连接池的最大连接数
jpc.setMaxTotal(30);  

// 设置连接池允许的最大空闲连接数
jpc.setMaxIdle(8);    

// 初始化连接池类,传入使用自定义连接池配置类
JedisPool jp = new JedisPool(jpc, "localhost", 6379);

// 从连接池获取一个Jedis连接
Jedis jedis = jp.getResource();

8、封装Jedis工具类

封装个工具类,方便后续使用,jedis.properties内容:

jedis.host=localhost
jedis.port=6379
jedis.username=admin
jedis.password=admin123
jedis.maxTotal=30
jedis.maxIdle=10

借助静态代码块,调用封装的静态方法获取连接对象时,执行静态代码块,完成连接池初始化。(复习:静态代码块在类加载时执行,且执行一次,而调用静态资源是类加载的触发时机之一)

public class JedisUtils {
	private static JedisPool pool;
	
	static {
		// 加载Jedis连接池配置参数
		InputStream inputStream = JedisUtils.class.getResourceAsStream("jedis.properties");
		Properties prop = new Properties();
		try {
			prop.load(inputStream);
		} catch (IOException e) {
			e.printStackTrace();
		}
		String host = prop.getProperty("jedis.host");
		int port = Integer.parseInt(prop.getProperty("jedis.port"));
		int maxTotal = Integer.parseInt(prop.getProperty("jedis.maxTotal"));
		int maxIdle = Integer.parseInt(prop.getProperty("jedis.maxIdle"));
		String username = prop.getProperty("jedis.username");
		String password = prop.getProperty("jedis.password");
		
		// 设置Jedis连接池参数
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(maxTotal);
		config.setMaxIdle(maxIdle);
		
		// 初始化Jedis连接池
		pool = new JedisPool(config, host, port,username,password);
	}
	
	// 从Jedis连接池获取连接
	public static Jedis getJedis() {
		return pool.getResource();
	}
}

8、RedisTemplate底层实现技术切换

RedisTemplate基于Jedis或Lettuce等连接池技术,实现了与Redis服务器的连接和资源管理。且SpringBoot下默认是使用Lettuce,这一点从starter中可以看到:

在这里插入图片描述

想实现底层技术的切换,即从默认的lettuce(翻译:生菜)切换成Jedis,只需引入依赖后指定配置中的client-type即可:

<dependency>
    <groupId>redis.clients</groupId>    
    <artifactId>jedis</artifactId>
</dependency>

改配置,准确说是在原来的基础说改下client-type:

spring:  
  redis:    
    host: localhost     
    port: 6379    
    client-type: jedis

其余独有属性可单独配置,Jedis和Lettuce的常用配置如连接池最大连接数:

spring:  
  redis:    
    host: localhost     
    port: 6379    
    client-type: jedis
    jedis:
      pool:
        max-active: 16
    # 顺便展示下Lettuce的,写一起了
    lettuce:
      pool:
        max-active: 16

关于Lettuce和Jedis的区别:

  • jedis连接Redis服务器是直连模式,当多线程模式下使用jedis会存在线程安全问题,解决方案可以通过配置连接池使每个连接专用,这样整体性能就大受影响
  • lettcus基于Netty框架进行与Redis服务器连接,底层设计中采用StatefulRedisConnection。 StatefulRedisConnection自身是线程安全的,可以保障并发访问安全问题,所以一个连接可以被多线程复用,当然lettcus也支持多连接实例一起工作

线程安全的这一点区别,大概就是Lettuce被选中做starter的默认实现的原因吧。

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

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

相关文章

基于Java的大学生社团管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

二十七、[进阶]MySQL默认存储引擎InnoDB的简单介绍

1、MySQL体系结构 MySQL大致可以分为连接层、服务层、引擎层、存储层四个层&#xff0c;这里需要注意&#xff0c;索引的结构操作是在存储引擎层完成的&#xff0c;所以不同的存储引擎&#xff0c;索引的结构是不一样的。 &#xff08;1&#xff09;体系结构示意图 &#xff0…

【数据结构】抽象数据类型

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 &#x1f38f;数据类型 &#x1f38f;抽象数据类型 结语 &#x1f38f;数据类型 数据类型:是指一组性质相同的值的集合及定义在此集合上的一些操作的总称. 数据类型(d…

【vue3】自定义hook函数

假期第三篇&#xff0c;对于基础的知识点&#xff0c;我感觉自己还是很薄弱的。 趁着假期&#xff0c;再去复习一遍 【vue3 】hook函数 hook本质上是一个函数&#xff0c;把setup中使用的Composition API进行了封装 假设需求是获取当前点击时鼠标的坐标 <template><…

Pycharm操作git仓库 合并等

菜单 Git CommitPushUpdate ProjectPullFetchMergreRebase 查询 查询分支 查询本地所有分支 # 查询本地分支 git branch# 查询远程分支 git branch -rPycharm查看当前分支 步骤&#xff1a; Git->Branches 哈喽&#xff0c;大家好&#xff0c;我是[有勇气的牛排]&…

网络正常,微信正常登录,谷歌浏览器无法正常打开(100%解决)

背景&#xff1a; 笔记本电脑&#xff0c;操作系统&#xff1a;windows10&#xff0c;网络&#xff1a;wifi/或者有线连接。 谷歌浏览器&#xff1a;最新版本&#xff1a;115.0.5790.171 可以正常使用微信&#xff0c;无法使用谷歌浏览器打开对应的网址。 解决办法&#xff1a;…

Charles 抓包工具使用详细介绍

1 前言 1.1 介绍 Charles是一款强大的网络抓包工具&#xff0c;主要用于分析和调试网络流量。它适用于多种操作系统&#xff0c;包括 Windows、macOS和linux。 Chaels可以捕获 http和https协议的请求和响应&#xff0c;帮助开发人员和测试人员了解应用程序与服务器支架的通信…

【2023双非保研】信管跨保计算机大类的记录(东南、川大、重大、东北、西电、南理工、杭高院、河海、东华、天大等)

以此篇博客记录我的保研之旅 目录 一、个人情况 二、夏令营 1、国科大杭高院&#xff08;线下&#xff09; 2、南信工&#xff08;线下&#xff09; 3、华中师范&#xff08;线上or线下&#xff09; 4、浙大软件&#xff08;线上&#xff09; 5、东华大学&#xff08;线…

手机电脑数码小程序商城的作用是什么

手机几乎是每个成年人人手一个以上&#xff0c;市场非常大&#xff0c;加之产品更新迭代速度快&#xff0c;每年都会推出多个型号、造型等&#xff0c;因此对高收入群体或爱机人群来说&#xff0c;新手机往往一年或二年时间就会换&#xff0c;或者直接购买当备用机等。 每个城…

C++ 学习系列 -- std::stack 与 std::queue

一 std::stack 与 std::queue 分别是什么&#xff1f; 两者均是 c 中的序列化容器&#xff0c;区别在于&#xff1a; std::stack 元素是先进后出 std::queue 元素是先进先出 二 std::stack 与 std::queue 原理 1 std:statck 2. std::queue 两者底层容器可以是 list 也可以…

创建型设计模式 单例 工厂模式 看这一篇就够了

4&#xff0c;创建型模式 创建型模式的主要关注点是“怎样创建对象&#xff1f;”&#xff0c;它的主要特点是“将对象的创建与使用分离”。 这样可以降低系统的耦合度&#xff0c;使用者不需要关注对象的创建细节。 创建型模式分为&#xff1a; 单例模式工厂方法模式抽象工程模…

vue3简易文字验证码

大神勿喷&#xff0c;简易版本&#xff0c;demo中可以用一下。 需要几个文字自己codelen 赋值 灵活点直接父组件传过去&#xff0c;可以自己改造 首先创建一个生成数字的js **mathcode.js**function MathCode(num){let str "寻寻觅觅冷冷清清凄凄惨惨戚戚乍暖还寒时候…

LeetCode 热题 HOT 100:回溯专题

LeetCode 热题 HOT 100&#xff1a;https://leetcode.cn/problem-list/2cktkvj/ 文章目录 17. 电话号码的字母组合22. 括号生成39. 组合总和46. 全排列补充&#xff1a;47. 全排列 II &#xff08;待优化)78. 子集79. 单词搜索124. 二叉树中的最大路径和200. 岛屿数量437. 路径…

object-fit,object-position让img标签表现得像背景图那样能自适应和调整显示位置

文章目录 一、object-fit的用法二、object-position的用法 图片在网页中有2种表现形式&#xff0c;使用CSS的background-image或者HTML的img标签来实现。 背景图实现如notion的封面图效果可以使用background-position或者background-size轻松实现&#xff0c;首先来看看notion…

2023年安全员-C证证模拟考试题库及安全员-C证理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年安全员-C证证模拟考试题库及安全员-C证理论考试试题是由安全生产模拟考试一点通提供&#xff0c;安全员-C证证模拟考试题库是根据安全员-C证最新版教材&#xff0c;安全员-C证大纲整理而成&#xff08;含2023年…

【Java 进阶篇】JDBC Statement:执行 SQL 语句的重要接口

在Java应用程序中&#xff0c;与数据库进行交互是一项常见的任务。为了执行数据库操作&#xff0c;我们需要使用JDBC&#xff08;Java Database Connectivity&#xff09;来建立与数据库的连接并执行SQL语句。Statement接口是JDBC中的一个重要接口&#xff0c;它用于执行SQL语句…

leetCode 376.摆动序列 贪心算法

如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为 摆动序列 。第一个差&#xff08;如果存在的话&#xff09;可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如&#xff0c; [1, 7, 4, 9, 2, 5] 是一个 摆动序列 &…

AI智能问答系统源码/AI绘画商业系统/支持GPT联网提问/支持Midjourney绘画

一、AI创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的AI智能问答系统和AI绘画系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图…

.360、.halo勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复

导言&#xff1a; 在网络犯罪的阴影下&#xff0c;.360和.halo勒索病毒显得格外神秘而危险&#xff0c;它们都属于BeijingCrypt勒索病毒家族旗下的病毒&#xff0c;两者加密特征一致&#xff0c;加密勒索信内容一致。本文91数据恢复将深度解析.360、.halo勒索病毒的内部机制&a…

【算法速查】一篇文章带你快速入门八大排序(上)

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;首先在这里祝大家中秋国庆双节同乐&#xff01;&#xff01;今天用一篇文章为大家把八大排序算法都过一遍&#xff0c;当然由于篇幅的原因不是每…