从0开始搭建一个生产级SpringBoot2.0.X项目(八)SpringBoot 使用Redis

 前言

最近有个想法想整理一个内容比较完整springboot项目初始化Demo。

SpringBoot使用Redis 缓存数据

一、 pom引入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.0.1-jre</version>
        </dependency>
      

二、 application-dev.yaml 增加redis 连接配置

spring:
  datasource:
    driver-class-name: oracle.jdbc.OracleDriver
    url: jdbc:oracle:thin:@//127.0.0.1:1521/orcl2
    username: murg_demo
    password: 654321
  hikari:
    connection-test-query: SELECT 1 FROM DUAL
    minimum-idle: 10
    maximum-pool-size: 50
    idle-timeout: 1200000
    max-lifetime: 1800000
    connection-timeout: 180000
  cache:
    redis:
      time-to-live: 1800s
  redis:
    host: 127.0.0.1
    port: 6379
    password: admin

logging:
  level:
    org.springframework.security: debug

三、创建RedisConfig类,规定序列化格式

package com.murg.bootdemo.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.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
    //redisTemplate注入到Spring容器
    @Bean
    public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String,String> redisTemplate=new RedisTemplate<>();
        //‌自定义序列化方式使用String序列化‌:可以简化操作并提高查找效率。
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        redisTemplate.setConnectionFactory(factory);
        //key序列化
        redisTemplate.setKeySerializer(redisSerializer);
        //value序列化
        redisTemplate.setValueSerializer(redisSerializer);
        //value hashmap序列化
        redisTemplate.setHashKeySerializer(redisSerializer);
        //key hashmap序列化
        redisTemplate.setHashValueSerializer(redisSerializer);
        return redisTemplate;
    }
}

四、创建RedisUtils 工具类

package com.murg.bootdemo.util;

import com.google.common.collect.HashMultimap;
import org.springframework.context.annotation.Bean;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @description: Redis工具类
 */
@Component
public class RedisUtils {

	private  static StringRedisTemplate redisTemplate;

	public RedisUtils(StringRedisTemplate redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	/**
	 * 写入缓存
	 *
	 * @param key   redis键
	 * @param value redis值
	 * @return 是否成功
	 */
	public static boolean set(final String key, String value) {
		boolean result = false;
		try {
			ValueOperations<String, String> operations = redisTemplate.opsForValue();
			operations.set(key, value);
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 写入缓存设置时效时间
	 *
	 * @param key   redis键
	 * @param value redis值
	 * @return 是否成功
	 */
	public static boolean set(final String key, String value, Long expireTime) {
		boolean result = false;
		try {
			ValueOperations<String, String> operations = redisTemplate.opsForValue();
			operations.set(key, value);
			redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 批量删除对应的键值对
	 *
	 * @param keys Redis键名数组
	 */
	public static void removeByKeys(final String... keys) {
		for (String key : keys) {
			remove(key);
		}
	}

	/**
	 * 批量删除Redis key
	 *
	 * @param pattern 键名包含字符串(如:myKey*)
	 */
	public static void removePattern(final String pattern) {
		Set<String> keys = redisTemplate.keys(pattern);
		if (keys != null && keys.size() > 0)
			redisTemplate.delete(keys);
	}

	/**
	 * 删除key,也删除对应的value
	 *
	 * @param key Redis键名
	 */
	public static void remove(final String key) {
		if (exists(key)) {
			redisTemplate.delete(key);
		}
	}

	/**
	 * 判断缓存中是否有对应的value
	 *
	 * @param key Redis键名
	 * @return 是否存在
	 */
	public static Boolean exists(final String key) {
		return redisTemplate.hasKey(key);
	}

	/**
	 * 读取缓存
	 *
	 * @param key Redis键名
	 * @return 是否存在
	 */
	public static String get(final String key) {
		String result = null;
		ValueOperations<String, String> operations = redisTemplate.opsForValue();
		result = operations.get(key);
		return result;
	}

	/**
	 * 哈希 添加
	 *
	 * @param key     Redis键
	 * @param hashKey 哈希键
	 * @param value   哈希值
	 */
	public static void hmSet(String key, String hashKey, String value) {
		HashOperations<String, String, String> hash = redisTemplate.opsForHash();
		hash.put(key, hashKey, value);
	}

	/**
	 * 哈希获取数据
	 *
	 * @param key     Redis键
	 * @param hashKey 哈希键
	 * @return 哈希值
	 */
	public static String hmGet(String key, String hashKey) {
		HashOperations<String, String, String> hash = redisTemplate.opsForHash();
		return hash.get(key, hashKey);
	}

	/**
	 * 判断hash是否存在键
	 *
	 * @param key     Redis键
	 * @param hashKey 哈希键
	 * @return 是否存在
	 */
	public static boolean hmHasKey(String key, String hashKey) {
		HashOperations<String, String, String> hash = redisTemplate.opsForHash();
		return hash.hasKey(key, hashKey);
	}

	/**
	 * 删除hash中一条或多条数据
	 *
	 * @param key      Redis键
	 * @param hashKeys 哈希键名数组
	 * @return 删除数量
	 */
	public static long hmRemove(String key, String... hashKeys) {
		HashOperations<String, String, String> hash = redisTemplate.opsForHash();
		return hash.delete(key, hashKeys);
	}

	/**
	 * 获取所有哈希键值对
	 *
	 * @param key Redis键名
	 * @return 哈希Map
	 */
	public static Map<String, String> hashMapGet(String key) {
		HashOperations<String, String, String> hash = redisTemplate.opsForHash();
		return hash.entries(key);
	}

	/**
	 * 保存Map到哈希
	 *
	 * @param key Redis键名
	 * @param map 哈希Map
	 */
	public static void hashMapSet(String key, Map<String, String> map) {
		HashOperations<String, String, String> hash = redisTemplate.opsForHash();
		hash.putAll(key, map);
	}

	/**
	 * 列表-追加值
	 *
	 * @param key   Redis键名
	 * @param value 列表值
	 */
	public static void lPush(String key, String value) {
		ListOperations<String, String> list = redisTemplate.opsForList();
		list.leftPush(key, value);
	}

	/**
	 * 列表-删除值
	 *
	 * @param key   Redis键名
	 * @param value 列表值
	 */
	public static void lRemove(String key, String value) {
		ListOperations<String, String> list = redisTemplate.opsForList();
		list.remove(key, 0, value);
	}




	/**
	 * 列表-获取指定范围数据
	 *
	 * @param key   Redis键名
	 * @param start 开始行号(start:0,end:-1查询所有值)
	 * @param end   结束行号
	 * @return 列表
	 */
	public static List<String> lRange(String key, long start, long end) {
		ListOperations<String, String> list = redisTemplate.opsForList();
		return list.range(key, start, end);
	}
	/**
	 * 集合添加
	 *
	 * @param key   Redis键名
	 * @param value 值
	 */
	public static void add(String key, String value) {
		SetOperations<String, String> set = redisTemplate.opsForSet();
		set.add(key, value);
	}

	/**
	 * 集合获取
	 *
	 * @param key Redis键名
	 * @return 集合
	 */
	public static Set<String> setMembers(String key) {
		SetOperations<String, String> set = redisTemplate.opsForSet();
		return set.members(key);
	}

	/**
	 * 有序集合添加
	 *
	 * @param key   Redis键名
	 * @param value 值
	 * @param score 排序号
	 */
	public static void zAdd(String key, String value, double score) {
		ZSetOperations<String, String> zSet = redisTemplate.opsForZSet();
		zSet.add(key, value, score);
	}

	/**
	 * 有序集合-获取指定范围
	 *
	 * @param key        Redis键
	 * @param startScore 开始序号
	 * @param endScore   结束序号
	 * @return 集合
	 */
	public static Set<String> rangeByScore(String key, double startScore, double endScore) {
		ZSetOperations<String, String> zset = redisTemplate.opsForZSet();
		return zset.rangeByScore(key, startScore, endScore);
	}

	/**
	 * 模糊查询Redis键名
	 *
	 * @param pattern 键名包含字符串(如:myKey*)
	 * @return 集合
	 */
	public static Set<String> keys(String pattern) {
		return redisTemplate.keys(pattern);
	}

	/**
	 * 获取多个hashMap
	 *
	 * @param keySet
	 * @return List<Map < String, String>> hashMap列表
	 */
	public static List hashMapList(Collection<String> keySet) {
		return redisTemplate.executePipelined(new SessionCallback<String>() {
			@Override
			public <K, V> String execute(RedisOperations<K, V> operations) throws DataAccessException {
				HashOperations hashOperations = operations.opsForHash();
				for (String key : keySet) {
					hashOperations.entries(key);
				}
				return null;
			}
		});
	}

	/**
	 * 保存多个哈希表(HashMap)(Redis键名可重复)
	 *
	 * @param batchMap Map<Redis键名,Map<键,值>>
	 */
	public static void batchHashMapSet(HashMultimap<String, Map<String, String>> batchMap) {
		// 设置5秒超时时间
		redisTemplate.expire("max", 25, TimeUnit.SECONDS);
		redisTemplate.executePipelined(new RedisCallback<List<Map<String, String>>>() {

			@Override
			public List<Map<String, String>> doInRedis(RedisConnection connection) throws DataAccessException {
				Iterator<Map.Entry<String, Map<String, String>>> iterator = batchMap.entries().iterator();
				while (iterator.hasNext()) {
					Map.Entry<String, Map<String, String>> hash = iterator.next();
					// 哈希名,即表名
					byte[] hashName = redisTemplate.getStringSerializer().serialize(hash.getKey());
					Map<String, String> hashValues = hash.getValue();
					Iterator<Map.Entry<String, String>> it = hashValues.entrySet().iterator();
					// 将元素序列化后缓存,即表的多条哈希记录
					Map<byte[], byte[]> hashes = new HashMap<byte[], byte[]>();
					while (it.hasNext()) {
						// hash中一条key-value记录
						Map.Entry<String, String> entry = it.next();
						byte[] key = redisTemplate.getStringSerializer().serialize(entry.getKey());
						byte[] value = redisTemplate.getStringSerializer().serialize(entry.getValue());
						hashes.put(key, value);
					}
					// 批量保存
					connection.hMSet(hashName, hashes);
				}
				return null;
			}
		});
	}

	/**
	 * 保存多个哈希表(HashMap)(Redis键名不可以重复)
	 *
	 * @param dataMap Map<Redis键名,Map<哈希键,哈希值>>
	 */
	public static void batchHashMapSet(Map<String, Map<String, String>> dataMap) {
		// 设置5秒超时时间
		redisTemplate.expire("max", 25, TimeUnit.SECONDS);
		redisTemplate.executePipelined(new RedisCallback<List<Map<String, String>>>() {

			@Override
			public List<Map<String, String>> doInRedis(RedisConnection connection) throws DataAccessException {
				Iterator<Map.Entry<String, Map<String, String>>> iterator = dataMap.entrySet().iterator();
				while (iterator.hasNext()) {
					Map.Entry<String, Map<String, String>> hash = iterator.next();
					// 哈希名,即表名
					byte[] hashName = redisTemplate.getStringSerializer().serialize(hash.getKey());
					Map<String, String> hashValues = hash.getValue();
					Iterator<Map.Entry<String, String>> it = hashValues.entrySet().iterator();
					// 将元素序列化后缓存,即表的多条哈希记录
					Map<byte[], byte[]> hashes = new HashMap<byte[], byte[]>();
					while (it.hasNext()) {
						// hash中一条key-value记录
						Map.Entry<String, String> entry = it.next();
						byte[] key = redisTemplate.getStringSerializer().serialize(entry.getKey());
						byte[] value = redisTemplate.getStringSerializer().serialize(entry.getValue());
						hashes.put(key, value);
					}
					// 批量保存
					connection.hMSet(hashName, hashes);
				}
				return null;
			}
		});
	}

	/**
	 * 保存多个哈希表(HashMap)列表(哈希map的Redis键名不能重复)
	 *
	 * @param list Map<Redis键名,Map<哈希键,哈希值>>
	 * @see RedisUtils*.batchHashMapSet()*
	 */
	public static void batchHashMapListSet(List<Map<String, Map<String, String>>> list) {
		// 设置5秒超时时间
		redisTemplate.expire("max", 25, TimeUnit.SECONDS);
		redisTemplate.executePipelined(new RedisCallback<List<Map<String, String>>>() {

			@Override
			public List<Map<String, String>> doInRedis(RedisConnection connection) throws DataAccessException {
				for (Map<String, Map<String, String>> dataMap : list) {
					Iterator<Map.Entry<String, Map<String, String>>> iterator = dataMap.entrySet().iterator();
					while (iterator.hasNext()) {
						Map.Entry<String, Map<String, String>> hash = iterator.next();
						// 哈希名,即表名
						byte[] hashName = redisTemplate.getStringSerializer().serialize(hash.getKey());
						Map<String, String> hashValues = hash.getValue();
						Iterator<Map.Entry<String, String>> it = hashValues.entrySet().iterator();
						// 将元素序列化后缓存,即表的多条哈希记录
						Map<byte[], byte[]> hashes = new HashMap<byte[], byte[]>();
						while (it.hasNext()) {
							// hash中一条key-value记录
							Map.Entry<String, String> entry = it.next();
							byte[] key = redisTemplate.getStringSerializer().serialize(entry.getKey());
							byte[] value = redisTemplate.getStringSerializer().serialize(entry.getValue());
							hashes.put(key, value);
						}
						// 批量保存
						connection.hMSet(hashName, hashes);
					}
				}
				return null;
			}
		});
	}

}

五、创建接口测试

TestRestController增加接口/testredis
    @RequestMapping(value = "/testredis", method = RequestMethod.GET)
    public WebResult testRedis() {
        RedisUtils.set("test","aaaaa");
        return WebResult.ok(RedisUtils.get("test"));
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

stuid学生信息

文章目录 前端准备MySQL数据库封装JDBC 连接工具类 DBUtil查寻学生新增学生 前端准备 结构 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width,…

ssm071北京集联软件科技有限公司信息管理系统+jsp(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;北京集联软件科技有限公司信息管理系统 \ 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本信息…

D62【python 接口自动化学习】- python基础之数据库

day62 SQL 基础 学习日期&#xff1a;20241108 学习目标&#xff1a;MySQL数据库-- 131 SQL基础和DDL 学习笔记&#xff1a; SQL的概述 SQL语言的分类 SQL的语法特征 DDL - 库管理 DDL - 表管理 总结 SQL是结构化查询语言&#xff0c;用于操作数据库&#xff0c;通用于绝大…

LongVU :Meta AI 的解锁长视频理解模型,利用自适应时空压缩技术彻底改变视频理解方式

Meta AI在视频理解方面取得了令人瞩目的里程碑式成就&#xff0c;推出了LongVU&#xff0c;这是一种开创性的模型&#xff0c;能够理解以前对人工智能系统来说具有挑战性的长视频。 研究论文 "LongVU&#xff1a;用于长视频语言理解的时空自适应压缩 "提出了一种革命…

golang分布式缓存项目 Day 1

注&#xff1a;该项目原作者&#xff1a;https://geektutu.com/post/geecache-day1.html。本文旨在记录本人做该项目时的一些疑惑解答以及部分的测试样例以便于本人复习。 LRU缓存淘汰策略 三种缓存淘汰策略 FIFO&#xff08;First In, First Out&#xff09;先进先出 原理&…

Axure设计之左右滚动组件教程(动态面板)

很多项目产品设计经常会遇到左右滚动的导航、图片展示、内容区域等&#xff0c;接下来我们用Axure来实现一下左右滚动的菜单导航。通过案例我们可以举一反三进行其他方式的滚动组件设计&#xff0c;如常见的上下滚动、翻页滚动等等。 一、效果展示&#xff1a; 1、点击“向左箭…

Rust项目结构

文章目录 一、module模块1.二进制文件的cargo项目2.库的cargo项目模块中使用crate关键字模块中使用super模块中结构体的访问规则模块中枚举的访问规则模块中use关键字不同模块定义了相同类型冲突解决办法使用pub use导出本模块的函数给外面模块引入外部依赖模块与子模块 小结3.…

分享:文本转换工具:PDF转图片,WORD转PDF,WORD转图片

前言 鉴于网上大多数在线转换工具要么需要收费&#xff0c;要么免费后但转换质量极差的情况&#xff0c;本人开发并提供了PDF转图片&#xff0c;WORD转PDF&#xff0c;WORD转图片等的文本转换工具。 地址 http://8.134.236.93/entry/login 账号 账号&#xff1a;STAR001&a…

【Linux探索学习】第十一弹——初识操作系统:冯诺依曼体系结构与操作系统的概念与定位

前言&#xff1a; 在学完我们前面的指令和工具之后&#xff0c;今天我们正式开启一个新的内容的学习——进程&#xff0c;在正式讲解进程之前&#xff0c;我们要先进入一些铺垫内容的学习&#xff0c;这就是我们今天要讲的冯诺依曼体系结构和操作系统的概念&#xff0c;下面我们…

Java:二维数组

目录 1. 二维数组的基础格式 1.1 二维数组变量的创建 —— 3种形式 1.2 二维数组的初始化 \1 动态初始化 \2 静态初始化 2. 二维数组的大小 和 内存分配 3. 二维数组的不规则初始化 4. 遍历二维数组 4.1 for循环 ​编辑 4.2 for-each循环 5. 二维数组 与 方法 5.1…

TVM计算图分割--分割方式

文章目录 TVM中的计算图分割方式1. Partition Pass2. dataflow_pattern3. 内置图分割接口4. Pipeline Executor5. BYOC框架6. UMA深度学习模型通常是用计算图来表示的。计算图是一种有向无环图,其中节点代表算子,表示一个操作,节点之间的边表示算子之间的数据依赖。计算图分…

RNA-seq 差异分析的点点滴滴(1)

引言 本系列[1])将开展全新的转录组分析专栏&#xff0c;主要针对使用DESeq2时可能出现的问题和方法进行展开。 为何使用未经标准化的计数数据&#xff1f; DESeq2 工具包在接收输入时&#xff0c;期望得到的是未经处理的原始计数数据&#xff0c;比如从 RNA-seq 或其他高通量测…

基于单片机的观赏类水草养殖智能控制系统的设计(论文+源码)

1总体设计 通过需求分析&#xff0c;本设计观赏类水草养殖智能控制系统的总体架构如图2.1所示&#xff0c;为系统总体设计框图。系统采用STM32单片机作为系统主控核心&#xff0c;利用DS18B20温度传感器、TDS传感器、CO2传感器、光敏传感器实现水草养殖环境中水温、CO2浓度、T…

中兴光猫修改SN,MAC,修改地区,异地注册,改桥接,路由拨号

前言 请先阅读上一篇博客获取到光猫超级密码电信光猫获取超级密码 电信光猫天翼网关4.0获取超级密码教程 四川电信光猫 中兴 F1855V2 ZXHN F1855V2 telent权限 实战 实测_天翼4.0光猫超级密码-CSDN博客 修改SN-修改地区&#xff0c;光猫异地注册&#xff0c;设置桥接模式&#…

基于卷积神经网络的农作物病虫害识别系统(pytorch框架,python源码)

更多图像分类、图像识别、目标检测等项目可从主页查看 功能演示&#xff1a; 基于卷积神经网络的农作物病虫害检测&#xff08;pytorch框架&#xff09;_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于卷积神经网络的农作物病虫害识别系统是在pytorch框架下实现的…

aardio 5分钟多线程开发简单入门

废话不多说 直接开干&#xff01; 借用作者话说 虽然 aardio 的多线程开发非常简单&#xff0c;但是&#xff1a; 1、请先了解:「多线程」开发比「单线程」开发更复杂这个残酷的现实。 2、请先了解: aardio 这样的动态语言可以实现真多线程非常罕见。 建议先找任意的编程语言试…

PMP–知识卡片--人才九宫格

在人才盘点时&#xff0c;根据人才的绩效和潜能&#xff0c;分别作为横坐标和纵坐标&#xff0c;将人才盘点的结果划分为9个象限&#xff0c;人才分为九个类别&#xff0c;以便于分类管理&#xff0c;因材施教。

1.每日SQL----2024/11/7

题目&#xff1a; 计算用户次日留存率,即用户第二天继续登录的概率 表&#xff1a; iddevice_iddate121382024-05-03232142024-05-09332142024-06-15465432024-08-13523152024-08-13623152024-08-14723152024-08-15832142024-05-09932142024-08-151065432024-08-131123152024-…

解决yum命令报错“Could not resolve host: mirrorlist.centos.org

这个主要是yum源出了问题或者服务器网络有问题&#xff0c;检查网络排除网络问题后&#xff0c;可更换源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.k wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.huaweicloud.com/repository…

qt QColorDialog详解

1、概述 QColorDialog是Qt框架中的一个对话框类&#xff0c;专门用于让用户选择颜色。它提供了一个标准的颜色选择界面&#xff0c;其中包括基本的颜色选择器&#xff08;如调色板和颜色轮&#xff09;、自定义颜色输入区域以及预定义颜色列表。QColorDialog支持RGB、HSV和十六…