系列十、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.pswp.cn/news/215684.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/215684.shtml
英文地址,請注明出處:http://en.pswp.cn/news/215684.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CStdioFile

CStdioFile 文件創建、數據寫入、寫入路徑 void StdReferenceDWG::RefDrawCrvt(StdOneReference& ref) {char* old_locale _strdup(setlocale(LC_CTYPE, NULL));setlocale(LC_CTYPE, "chs");//設定CString strPath StdTool::GetCurPath() _T("襯圖\\Re…

界面控件DevExpress中文教程 - 如何用Office File API組件填充PDF表單

DevExpress Office File API是一個專為C#, VB.NET 和 ASP.NET等開發人員提供的非可視化.NET庫。有了這個庫&#xff0c;不用安裝Microsoft Office&#xff0c;就可以完全自動處理Excel、Word等文檔。開發人員使用一個非常易于操作的API就可以生成XLS, XLSx, DOC, DOCx, RTF, CS…

基于SpringBoot的就業信息管理系統設計與實現(源碼+數據庫+文檔)

摘 要 在新冠肺炎疫情的影響下&#xff0c;大學生的就業問題已經變成了一個引起人們普遍重視的社會焦點問題。在這次疫情的沖擊之下&#xff0c;大學生的就業市場的供求雙方都受到了不同程度的影響&#xff0c;大學生的就業情況并不十分樂觀。目前&#xff0c;各種招聘平臺上…

Netty高性能的原因

Netty 之所以具有高性能&#xff0c;主要得益于以下幾個方面的設計和實現&#xff1a; 異步非阻塞&#xff1a; Netty采用基于事件驅動的異步非阻塞模型&#xff0c;即 Reactor 模式。這意味著它能夠處理大量并發連接而不會因為I/O操作而阻塞線程。不會因為每個連接都需要一個單…

云原生之使用Docker部署Mariadb數據庫

目錄 一、什么是云原生 二、Docker介紹 三、Mariadb數據庫介紹 四、如何使用Docker部署Mariadb數據庫 一、什么是云原生 云原生是一種綜合性的技術和方法論&#xff0c;旨在對應用程序進行全生命周期的管理&#xff0c;包括開發、部署、運行和擴展。它倡導將應用程序設計為…

moviepy基本參數用法大全

閱讀本文檔的前置說明&#xff1a; 本文檔用于講解Python的moviepy庫的自帶函數的用法&#xff0c;主要目的是講一下每個函數的每個參數的含義&#xff0c;無需一開始就全部掌握&#xff0c;粗略看一下就行&#xff0c;可以在后面自己開發過程&#xff0c;遇到不會用的函數再回…

大模型應用_AutoGPT

1 功能 整體功能&#xff0c;想解決什么問題 單獨使用 ChatGPT 時&#xff0c;只提供基本的聊天&#xff0c;無法實現具體的功能&#xff0c;如果想提供某種功能&#xff0c;則需要結合程序實現。AutoGPT目標是建立和使用 AI Agent&#xff0c;設定一個或多個目標&#xff0c;…

數據庫——字段拆分與合并

一、GP或PostgreSQL 1.字段拆分成行 unnest(string_to_array(test, ,)) 例如某一字段值為"a,b,c,d"&#xff0c;使用string_to_array將其拆分為數組&#xff0c;然后使用unnest將數組平鋪成一張表 SELECT unnest(string_to_array(555,666,777, ,)) 2.字段拆分成列…

【EI征稿倒計時3天】第四屆IEEE信息科學與教育國際學術會議(ICISE-IE 2023)

第四屆IEEE信息科學與教育國際學術會議(ICISE-IE 2023) 2023 4th International Conference on Information Science and Education&#xff08;ICISE-IE 2023&#xff09; ICISE-IE2024已上線嶺南師范學院官網&#xff08;點擊查看&#xff09; 第四屆IEEE信息科學與教育國…

雙熒光素酶報告基因檢測(五)

關于雙熒光素酶報告基因檢測中遇到的問題及解決措施 問題1&#xff1a;為什么要用熒光素酶實驗來做檢測&#xff0c;不用其他報告基因來做&#xff0c;GFP可以嗎&#xff1f; 采用熒光素酶來做實驗是由其自身的優勢所決定的&#xff1a;&#xff08;1&#xff09;蛋白不需要翻…

@Transactional失效問題

作者簡介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中興通訊、美團架構師&#xff0c;現某互聯網公司CTO 聯系qq&#xff1a;184480602&#xff0c;加我進群&#xff0c;大家一起學習&#xff0c;一起進步&#xff0c;一起對抗互聯網寒冬 關于Transactional 日…

解讀 | 為什么有很多名人讓人們警惕人工智能

大家好&#xff0c;我是極智視界&#xff0c;歡迎關注我的公眾號&#xff0c;獲取我的更多前沿科技分享 邀您加入我的知識星球「極智視界」&#xff0c;星球內有超多好玩的項目實戰源碼和資源下載&#xff0c;鏈接&#xff1a;https://t.zsxq.com/0aiNxERDq 這個話題總能引起很…

六、ZGC深度剖析

一、引言 對于Java 程序員來說&#xff0c;JVM 幫助我們做了很多事情。 JVM是虛擬機&#xff0c;能夠識別字節碼&#xff0c;就是class文件或者你打包的jar文件&#xff0c;運行在操作系統上。 JVM幫我們實現了跨平臺&#xff0c;你只需要編譯一次&#xff0c;就可以在不同的…

在線課堂知識付費小程序源碼系統 開發組合PHP+MySQL:用手機隨時隨地地學習,講師親自在線授業解惑 帶安裝部署教程

近年來&#xff0c;人們對于學習的需求也日益增加。傳統的課堂教學已經無法滿足人們的學習需求&#xff0c;而在線課堂則能夠讓人們隨時隨地地進行學習。同時&#xff0c;隨著知識付費的興起&#xff0c;越來越多的講師也愿意將自己的知識和經驗分享給更多的人。因此&#xff0…

Mysql社區版日志審計插件

過去從Mysql官方自帶general.log日志的相比其他插件性能是最差的&#xff0c;我們考慮參考行業中較好的插件是MariaDB Audit Plugin, 可惜并不兼容mysql 5.7與mysql 8.0以上版本。 采用github開源項目&#xff0c;該項目支持MySQL 5.7和MySQL 8.0兩個分支。 https://github.c…

如何管理醫療設備用電?這才是最佳方法!

隨著社會對可持續發展和環保的關注不斷上升&#xff0c;蓄電池監控系統作為能源存儲和管理的關鍵技術&#xff0c;正在嶄露頭角。 蓄電池監控系統不僅為能源行業帶來了新的可能性&#xff0c;同時也為各個領域的能源使用者提供了更加智能、高效的解決方案。 客戶案例 工業生產…

ansible部署安裝Tomcat

我們需要用到的文件jdk以及tomcat安裝包 下載鏈接:https://pan.baidu.com/s/1sjG8Yl8k-SUbOv7KwKXZMA 提取碼&#xff1a;t71z 準備n臺機器&#xff08;我這里就簡單部署三臺機器&#xff09; ansible的安裝部署以及配置可以看博主之前的文章自動化運維工具-ansible部署 ansib…

建筑可視化數據大屏匯總,UI源文件(PC端大屏設計)

酷炫的大屏設計讓數據更好的展現&#xff0c;方便業務人員分析數據&#xff0c;輔助領導決策。現在分享大屏Photoshop源文件&#xff0c;以下為部分截圖示意。 劃重點&#xff1a;文末可獲得完整素材包~ 01 科技建筑平臺數據可視化 02 建筑公司可視化數據匯總平臺 03 深藍…

計算機視覺-機器學習-人工智能 頂會會議召開地址

計算機視覺-機器學習-人工智能 頂會會議召開地址 最近應該要整理中文資料的參考文獻&#xff0c;很多會議文獻都需要補全會議地點&#xff08;新國標要求&#xff09;。四處百度感覺也挺麻煩的&#xff0c;而且沒有比較齊全的網站可以搜索。因此自己整理了一下計算機視覺-機器…

JVM虛擬機系統性學習-對象存活判斷算法、對象引用類型和垃圾清除算法

垃圾回收 在 JVM 中需要對沒有被引用的對象&#xff0c;也就是垃圾對象進行垃圾回收 對象存活判斷算法 判斷對象存活有兩種方式&#xff1a;引用計數法、可達性分析算法 引用計數法 引用計數法通過記錄每個對象被引用的次數&#xff0c;例如對象 A 被引用 1 次&#xff0c…