系列十、SpringBoot + MyBatis + Redis实现分布式缓存(基于注解方式)

一、概述

        上篇文章 系列九、SpringBoot + MyBatis + Redis实现分布式缓存 介绍了基于xml方式实现分布式缓存的效果,当前大家使用的技术栈基本是springboot+各种框架的组合,而springboot显著的一个特点就是去xml配置,那么在无xml配置的情形下,又该如何实现分布式缓存呢?请看下面的代码实战

二、代码实战

2.1、分布式缓存相关的注解

        基于注解方式的分布式缓存,主要涉及到如下几个注解:

        (1)@EnableCaching:一般标注在配置类上,表示开启Spring的缓存,如果不加此注解的话Spring自带的缓存将不生效;

        (2)@CacheConfig(cacheNames = "xxx"):一般标注在service类上,用于配置cache的名字,建议以当前service类的全路径名作为cache的名字;

        (3)@Cacheable:一般标识在service层的查询方法上,表示将一个方法的返回值缓存起来,  默认情况下,缓存的key就是方法的参数,缓存的value就是方法的返回值,如果查询 方法无参数,则会使用默认的key,即SimpleKey [];

        (4)@CachePut(key = "#department.id"):一般加在service层的更新方法上(update),当数据库中的数据更新后,缓存中的数据也要跟着更新,使用此注解,可以将方法的返回值 自动更新到已经存在的key上

        (5)@CacheEvict:一般加在service层的删除方法上,当数据库中的数据删除后,相关的缓存也会被删除,使用该注解的时候,也可以配置按照某种条件删除(某种条件:@CacheEvict注解中的条件,例如:value、cacheNames、key、keyGenerator...)

2.2、项目概览

2.3、pom

<dependencies><!-- springboot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><!-- 数据源 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.26</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.10</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- 工具 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.21</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.4</version></dependency><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.25</version></dependency></dependencies>

2.4、yml

server:port: 9999spring:redis:host: port: 6379database: 0password: 123456datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/20231018_redis?useSSL=false&useUnicode=true&characterEncoding=UTF8&serverTimezone=GMTusername: rootpassword: 123456mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: org.stat.entity.modelconfiguration:map-underscore-to-camel-case: truelogging:level:org:star:mapper: debug

2.5、主启动

/*** @Author : 一叶浮萍归大海* @Date: 2023/12/10 12:44* @Description:**/
@MapperScan(basePackages = "org.star.mapper")
@SpringBootApplication
public class SpringbootRedisDistributeCacheAnnotationApplication {public static void main(String[] args) {SpringApplication.run(SpringbootRedisDistributeCacheAnnotationApplication.class, args);}}

2.6、MyRedisConfig

/*** @Author : 一叶浮萍归大海* @Date: 2023/12/10 15:28* @Description:* @EnableCaching的作用:开启Spring的缓存,如果不加此注解的话Spring自带的缓存将不生效**/
@EnableCaching
@Configuration
public class MyRedisConfig {/*** RedisTemplate k v 序列化** @param connectionFactory* @return*/@Beanpublic RedisTemplate<Object, Object> redisTemplate(LettuceConnectionFactory connectionFactory) {RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(connectionFactory);redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());redisTemplate.setHashKeySerializer(RedisSerializer.string());redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());redisTemplate.afterPropertiesSet();return redisTemplate;}@Beanpublic RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()// 设置默认的超时时间为2小时.entryTtl(Duration.ofHours(2)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()))// 设置默认的缓存前缀.prefixCacheNameWith("REDIS_CACHE_");return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);}}

2.7、DepartmentDO

/*** @Author : 一叶浮萍归大海* @Date: 2023/12/10 12:48* @Description:*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
public class DepartmentDO implements Serializable {/*** 编号*/private Integer id;/*** 部门名称*/private String departmentName;}

2.8、DepartmentMapper.java

/*** @Author : 一叶浮萍归大海* @Date: 2023/12/10 12:50* @Description:*/
public interface DepartmentMapper {/*** 查询所有部门* @return*/List<DepartmentDO> listAllDepartment();/*** 根据id查询部门信息* @param id* @return*/DepartmentDO getDepartmentById(Integer id);/*** 根据id和departmentName查询部门* @param id* @param departmentName* @return*/DepartmentDO getDepartment(Integer id,String departmentName);/*** 更新Department* @param department* @return*/int updateDepartment(DepartmentDO department);/*** 删除部门* @param id*/void deleteDepartment(Integer id);
}

2.9、DepartmentMapper.xml

<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="org.star.mapper.DepartmentMapper"><select id="listAllDepartment" resultType="org.star.entity.model.DepartmentDO">select id,department_name from department</select><select id="getDepartmentById" resultType="org.star.entity.model.DepartmentDO">select id,department_name from department where id = #{id}</select><select id="getDepartment" resultType="org.star.entity.model.DepartmentDO">select id,department_name from department where id = #{id} and department_name = #{departmentName}</select><update id="updateDepartment" useGeneratedKeys="true" keyProperty="id">update department set department_name = #{departmentName} where id = #{id}<selectKey resultType="org.star.entity.model.DepartmentDO" order="AFTER" keyProperty="id">select id,department_name from department where id = #{id}</selectKey></update><delete id="deleteDepartment">delete from department where id = #{id}</delete></mapper>

2.10、DepartmentService

/*** @Author : 一叶浮萍归大海* @Date: 2023/12/10 20:00* @Description:* 基于注解的分布式缓存,redis中key的生成规则:${prefixCacheNameWith} + "_" + ${cacheNames} + "_" + ${key}*      说明:prefixCacheNameWith为RedisCacheManager中配置的前缀*      举例:*          (1)listAllDepartment ===> REDIS_CACHE_org.star.service.DepartmentService::SimpleKey []*          (2)getDepartmentById ===> REDIS_CACHE_org.star.service.DepartmentService::1*          (3)getDepartment ===> REDIS_CACHE_org.star.service.DepartmentService::SimpleKey [1,研发部]**/
@Service
@CacheConfig(cacheNames = "org.star.service.DepartmentService")
public class DepartmentService {@Resourceprivate DepartmentMapper departmentMapper;/*** @return* @Cacheable的作用:*      @Cacheable注解一般加在查询方法上,表示将一个方法的返回值缓存起来,* 默认情况下,缓存的key就是方法的参数,缓存的value就是方法的返回值,如果查询* 方法无参数,则会使用默认的key,即SimpleKey []*/@Cacheablepublic List<DepartmentDO> listAllDepartment() {List<DepartmentDO> departments = departmentMapper.listAllDepartment();return departments;}/*** 对于只有一个参数的查询方法,其key位id对应的值* @param id* @return*/@Cacheablepublic DepartmentDO getDepartmentById(Integer id) {return departmentMapper.getDepartmentById(id);}/**** 对于有多个参数的查询方法,其key为所有的参数,如果想修改,可以单独指定,例如:@Cacheable(key = "#id")* @param id* @param departmentName* @return*/@Cacheablepublic DepartmentDO getDepartment(Integer id,String departmentName) {return departmentMapper.getDepartment(id,departmentName);}/*** @CachePut作用:*      @CachePut注解一般加在更新方法上(update),当数据库中的数据更新后,缓存中的数据也要跟着更新,使用此注解,可以将方法的返回值*      自动更新到已经存在的key上,示例如下:* @param department* @return*/@CachePut(key = "#department.id")public DepartmentDO updateDepartment(DepartmentDO department) {departmentMapper.updateDepartment(department);return department;}/*** @CacheEvict()作用:*      @CacheEvict()注解一般加在删除方法上,当数据库中的数据删除后,相关的缓存也会被删除,使用该注解的时候,也可以配置按照某种条件*      删除(某种条件:@CacheEvict注解中的条件,例如:value、cacheNames、key、keyGenerator...)* @param id*/@CacheEvictpublic void deleteDepartment(Integer id) {departmentMapper.deleteDepartment(id);}}

2.11、DepartmentServiceTest

/*** @Author : 一叶浮萍归大海* @Date: 2023/12/10 20:07* @Description:*/
@SpringBootTest
public class DepartmentServiceTest {@Resourceprivate DepartmentService departmentService;@Testpublic void listAllDepartmentTest() {List<DepartmentDO> departments1 = departmentService.listAllDepartment();System.out.println("departments1 = " + departments1);System.out.println("=============================");List<DepartmentDO> departments2 = departmentService.listAllDepartment();System.out.println("departments2 = " + departments2);}@Testpublic void getDepartmentByIdTest() {DepartmentDO department1 = departmentService.getDepartmentById(1);System.out.println("department1 = " + department1);System.out.println("========================");DepartmentDO department2 = departmentService.getDepartmentById(1);System.out.println("department2 = " + department2);}@Testpublic void getDepartmentTest() {DepartmentDO department1 = departmentService.getDepartment(1, "研发部");System.out.println("department1 = " + department1);System.out.println("============================");DepartmentDO department2 = departmentService.getDepartment(1, "研发部");System.out.println("department2 = " + department2);}@Testpublic void updateDepartmentTest() {DepartmentDO department = new DepartmentDO().setDepartmentName("研发部444").setId(1);DepartmentDO updatedDepartment = departmentService.updateDepartment(department);System.out.println("updatedDepartment = " + updatedDepartment);}@Testpublic void deleteDepartmentTest() {departmentService.deleteDepartment(1);}}

2.12、测试

2.12.1、listAllDepartmentTest

2.12.2、 getDepartmentByIdTest

2.12.3、getDepartmentTest

2.12.4、 updateDepartmentTest

2.12.5、 deleteDepartmentTest

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

痤疮分割 实验心路历程

数据集的制作 将labelme生成的标注文件记普通的json文件转成coco数据集格式的json文件 图像分辨率过大 如果不做任何调整&#xff1a; 会出现“killed”的报错&#xff0c;表示图片像素过大&#xff0c;显卡内存不够&#xff0c;无法支撑训练 显卡 换成更高性能的显卡&am…

12.11 C++ 作业

完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和密码不匹配&#xf…

【操作系统和计网从入门到深入】(二)进程

前言 这个专栏其实是博主在复习操作系统和计算机网络时候的笔记&#xff0c;所以如果是博主比较熟悉的知识点&#xff0c;博主可能就直接跳过了&#xff0c;但是所有重要的知识点&#xff0c;在这个专栏里面都会提到&#xff01;而且我也一定会保证这个专栏知识点的完整性&…

IP与以太网的转发操作

TCP模块在执行连接、收发、断开等各阶段操作时&#xff0c;都需要委托IP模块将数据封装成包发送给通信对象。 网络中有路由器和集线器两种不同的转发设备&#xff0c;它们在传输网络包时有着各自的分工。 (1)路由器根据目标地址判断下一个路由器的位置 (2)集线器在子网中将网…

Java学习总结

1. Java集合体系框架 java.util中包含 Java 最常用的the collections framework。 Java集合类主要由两个根接口Collection和Map派生出来的。 Collection 接口派生出了三个子接口List、Set、Queue。Map 接口 因此Java集合大致也可分成List、Set、Queue、Map四种接口体系。 …

diffusers pipeline拆解:理解pipelines、models和schedulers

diffusers pipeline拆解&#xff1a;理解pipelines、models和schedulers 翻译自&#xff1a;https://huggingface.co/docs/diffusers/using-diffusers/write_own_pipeline v0.24.0 diffusers 设计初衷就是作为一个简单且易用的工具包&#xff0c;来帮助你在自己的使用场景中构建…

Django讲课笔记02:Django环境搭建

文章目录 一、学习目标二、相关概念&#xff08;一&#xff09;Python&#xff08;二&#xff09;Django 三、环境搭建&#xff08;一&#xff09;安装Python1. 从官方网站下载最新版本的Python2. 运行安装程序并按照安装向导进行操作3. 勾选添加到路径复选框4. 完成安装过程5.…

记录 | xftp远程连接两台windows

1、打开openssh 设置 -> 应用 -> 可选功能 -> 添加功能 -> OpenSSH 客户端&#xff0c;将 ssh 客户端安装将两台电脑的 ssh 开启&#xff0c;cmd 中输入 net start sshd2、配置 win10 账号密码 3、进行 xftp 连接

移液器吸头材质选择——PFA吸头在半导体化工行业的应用

PFA吸头是一种高性能移液器配件&#xff0c;这种材料具有优异的耐化学品、耐热和电绝缘性能&#xff0c;使得PFA吸头在应用中表现出色。那么它有哪些特点呢&#xff1f; 首先&#xff0c;PFA吸头具有卓越的耐化学腐蚀性能。无论是酸性溶液、碱性溶液还是有机溶剂&#xff0c;P…

做数据分析为何要学统计学(5)——什么问题适合使用卡方检验?

卡方检验作为一种非常著名的非参数检验方法&#xff08;不受总体分布因素的限制&#xff09;&#xff0c;在工程试验、临床试验、社会调查等领域被广泛应用。但是也正是因为使用的便捷性&#xff0c;造成时常被误用。本文参阅相关的文献&#xff0c;对卡方检验的适用性进行粗浅…

(代码详解)饼图绘制+参数讲解+饼图内外标签字体大小设置+添加图例,并调整图例大小与位置+调整标题与图之间的距离

大家好&#xff0c;本篇的目的是使用python画出如下的饼图&#xff0c;并且介绍其中参数的作用 目录 完整代码 一、导入所需的库 二、中文显示 三、调整图例的大小(长、宽) 四、导入数据 五、绘制饼图参数介绍 &#xff08;重点&#xff09; 六、调整饼图外标签和内标签…

SpringBoot3-集成mybatis

1、pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.…

Java EE 多线程之多线程案例

文章目录 1. 多线程案例1.1 单例模式1.1.1 饿汉模式1.1.2 懒汉模式1.1.3 多线程下的单例模式 1.2 阻塞队列1.2.1 阻塞队列定义1.2.2 生产者消费者模型的意义1.2.4 标准库中的阻塞队列1.2.5 实现阻塞队列1.2.6 用阻塞队列实现生产者消费者模型 1.3 实现定时器1.3.1 标准库中的定…

酷开科技多维度赋能营销,实力斩获三项大奖

在数智化新阶段、广告新生态、传播新业态的背景下&#xff0c;“第30届中国国际广告节广告主盛典暨网易传媒态度营销峰会”于11月18日在厦门国际会展中心盛大举行。来自全国的品牌方、战略决策者、媒体平台和品牌服务机构等汇聚一堂。在50000&#xff0b;现场观众和数千万线上观…

Altman作了多少恶?排挤首席科学家出GPT5开发、离间董事会、PUA员工

在山姆奥特曼&#xff08;Sam Altman&#xff09;被OpenAI董事会突然解职后的几天里&#xff0c;这个消息在科技圈引发轰动&#xff0c;该公司内部员工和许多科技界人士甚至将此举比作一场政变。 奥特曼被解雇后立即传出的说法是&#xff0c;OpenAI的广大员工都很喜欢他&#x…

打包CSS

接上一个打包HTML继续进行CSS的打包 1.在之前的文件夹里的src文件夹创建一个css文件 2.在浏览器打开webpack——>中文文档——>指南——>管理资源——>加载CSS 3.复制第一句代码到终端 4.复制下图代码到webpack.config.js脚本的plugins&#xff1a;[.....]内容下…

android项目实战之编辑器集成

引言 项目需要用到编辑器&#xff0c;采用RichEditor&#xff0c;如下效果 实现 1. 引入库2 implementation jp.wasabeef:richeditor-android:2.0.0 2. XML <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width&q…

持续集成和持续交付

引言 CI/CD 是一种通过在应用开发阶段引入自动化来频繁向客户交付应用的方法。CI/CD 的核心概念是持续集成、持续交付和持续部署。作为一种面向开发和运维团队的解决方案&#xff0c;CI/CD 主要针对在集成新代码时所引发的问题&#xff08;亦称&#xff1a;“集成地狱”&#…

ubuntu install sqlmap

refer: https://github.com/sqlmapproject/sqlmap 安装sqlmap&#xff0c;可以直接使用git 克隆整个sqlmap项目&#xff1a; git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev 2.然后进入sqlmap-dev&#xff0c;使用命令&#xff1a; python s…

ARP协议:地址解析协议

目录 引言 什么是ARP协议&#xff1f; ARP协议的工作原理 1. ARP请求 2. ARP应答 3. ARP缓存 ARP协议的应用 结语 其他链接 引言 在计算机网络中&#xff0c;地址解析协议&#xff08;ARP&#xff0c;Address Resolution Protocol&#xff09;扮演着重要的角色。ARP协议…