日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

springboot-cache的简单使用

發(fā)布時(shí)間:2025/3/19 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 springboot-cache的简单使用 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

springboot-cache 的簡(jiǎn)單使用

springboot-cache介紹

一、前言

Spring Cache 對(duì) Cahce 進(jìn)行了抽象,提供了 @Cacheable、@CachePut、@CacheEvict 等注解。Spring Boot 應(yīng)用基于 Spring Cache,既提供了基于內(nèi)存實(shí)現(xiàn)的緩存管理器,可以用于單體應(yīng)用系統(tǒng),也集成了 Redis 等緩存服務(wù)器,可以用于大型系統(tǒng)或者分布式系統(tǒng)。

二、關(guān)于 Cache

應(yīng)用系統(tǒng)需要通過(guò) Cache 來(lái)緩存不經(jīng)常改變的數(shù)據(jù)以提高系統(tǒng)性能和增加系統(tǒng)吞吐量,避免直接訪問(wèn)數(shù)據(jù)庫(kù)等低速的存儲(chǔ)系統(tǒng)。緩存的數(shù)據(jù)通常存放在訪問(wèn)速度更快的內(nèi)存中或者是低延遲存取的存儲(chǔ)器、服務(wù)器上。緩存系統(tǒng)存儲(chǔ)大都是不經(jīng)常改變的業(yè)務(wù)數(shù)據(jù),如用戶(hù)權(quán)限、字典數(shù)據(jù)、配置信息等等。

springboot-cache的注解講解

1、@Cacheable注解

@Cacheable注解的作用是Spring在調(diào)用該方法之前,首先在緩存中查找方法的返回值,默認(rèn)的key是根據(jù)參數(shù)值生成,如果存在,直接返回緩存中的值,否則執(zhí)行該方法,并將返回值保存到緩存中

@Cacheable運(yùn)行流程:

1.方法運(yùn)行之前,先去查詢(xún)Cache(緩存組件),按照cacheNames指定的名字獲取;

? (CacheManager先獲取相應(yīng)的緩存),第一次獲取緩存如果沒(méi)有Cache組件會(huì)自動(dòng)創(chuàng)建。

2.去Cache中查找緩存的內(nèi)容,使用一個(gè)key,默認(rèn)就是方法的參數(shù)值;

  • ? key是按照某種策略生成的;默認(rèn)是使用keyGenerator生成的,

  • Spring默認(rèn)加載的是SimpleCacheManage,SimpleKeyGenerator生成key的默認(rèn)策略是:

  • ? 如果沒(méi)有參數(shù);key=new SimpleKey()

  • ? 如果有一個(gè)參數(shù):key=參數(shù)的值

  • ? 如果有多個(gè)參數(shù):key=new SimpleKey(params)

3.沒(méi)有查到緩存就調(diào)用目標(biāo)方法;

4.將目標(biāo)方法返回的結(jié)果,放進(jìn)緩存中

@Cacheable屬性說(shuō)明:

1.acheNames/value:該屬性值必須提供,指定緩存組件的名字,將方法的返回結(jié)果放在哪個(gè)緩存中,是數(shù)組的 方式,可以指定多個(gè)緩存;

如:cacheNames = "product"或者cacheNames = {“product1”,“product2”}

2.key:緩存數(shù)據(jù)使用的key,不指定key則默認(rèn)是使用方法參數(shù)的值該屬性值支持SpEL表達(dá)式

3.cacheManager:指定緩存管理器;或者cacheResolver指定獲取解析器

4.condition:指定符合條件的情況下才緩存 condition = “#a0=1” 當(dāng)方法中第一個(gè)參數(shù)=1的時(shí)候才進(jìn)行緩存

5.unless:否定緩存;當(dāng)unless指定的條件為true,方法的返回值就不會(huì)被緩存;可以獲取到結(jié)果進(jìn)行判斷

? unless = “#result == null”

? unless = “#a0==2”:如果第一個(gè)參數(shù)的值是2,結(jié)果不緩存;

6.sync:是否使用異步模式

使用樣例:

/** @Author crush* 原理:* 運(yùn)行流程:* @Cacheable* 1 方法執(zhí)行之前 先去查詢(xún)Cache (緩存組件) 按照cacheNames 指定的名字獲取* 先去獲取相應(yīng)的緩存 第一次獲取緩存如果沒(méi)有 Cache組件會(huì)自動(dòng)創(chuàng)建* 2 去Cache 中查找緩存的內(nèi)容 使用一個(gè)key 默認(rèn)就是方法的參數(shù)* 3 沒(méi)有查到就返回結(jié)果* 4 將目標(biāo)方法返回的結(jié)果 放進(jìn)緩存中** @Cacheable 標(biāo)注的方法 執(zhí)行之前 先來(lái)檢查緩存中有沒(méi)有這個(gè)數(shù)據(jù) 默認(rèn)按照參數(shù)的值作為key去查詢(xún)緩存* 如果沒(méi)有就運(yùn)行方法并將結(jié)果放入緩存* 屬性:* cacheNames :指定緩存組的名字* key:緩存數(shù)據(jù)用的key* keyGenerator : 也可以用這個(gè)自定義key的值* condition: 指定符合條件下菜緩存 condition="#id>0"* // #a0> 1 表示第一個(gè)參數(shù)大與1* unless:否定緩存* unless="#a0==2" 如果第一個(gè)參數(shù)是2 就不緩存* sync:是否使用異步模式**/@Cacheable(cacheNames = "userInfo",key = "#user_id",condition = "#id=1") // #a0> 1 表示第一個(gè)參數(shù)大與1public UserInfo selectByUserId(String user_id) {System.out.println("根據(jù)id查詢(xún)用戶(hù)");return userInfoMapper.selectByUserId(user_id);}

2、自定義Key生成器

除了通過(guò)SPEL表達(dá)式之外,還可以通過(guò)自定義key生成器的方式,Spring緩存模塊提供了org.springframework.cache.interceptor.KeyGenerator接口用于緩存key的生成聲明,因此我們可以自定義一個(gè)MyKeyGenerator類(lèi)并實(shí)現(xiàn)了KeyGenerator接口 ,使用如下:

import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import java.lang.reflect.Method; import java.util.Arrays;@Configuration public class MyCacheConfig {@Beanpublic KeyGenerator myKeyGenerator(){return new KeyGenerator(){public Object generate(Object target, Method method, Object... params) {return method.getName()+"["+ Arrays.asList(params).toString()+"]";}};} }

該方法測(cè)試用,關(guān)于緩存key的生成方式,網(wǎng)上有很多種策略。

使用時(shí)只需要修改注解的key屬性即可:

@Cacheable(cacheNames = "product",keyGenerator = "myKeyGenerator")

3、 @CachePut

@CachePut注解的作用簡(jiǎn)單的說(shuō)一句話:既調(diào)用方法,又緩存數(shù)據(jù)。

/** @Author crush* @CachePut 即調(diào)用方法 有更新緩存數(shù)據(jù)* 運(yùn)行時(shí)機(jī):* 1 先調(diào)用目標(biāo)方法* 2 將目標(biāo)方法的結(jié)果緩存起來(lái)* 測(cè)試:* 1 先去查詢(xún)* 2 然后再更新* 3 然后再執(zhí)行查詢(xún) 發(fā)現(xiàn)還是更新之前的數(shù)據(jù)* 4 發(fā)現(xiàn)他們緩存的時(shí)候 使用的key 是不一樣的 這個(gè)時(shí)候要使用相同的key***/ @CachePut(/*value = "userInfo", */key = "#userInfo.user_id") public UserInfo updateUser(UserInfo userInfo) {System.out.println("更新用戶(hù)信息");userInfoMapper.updateUser(userInfo);return userInfo; }

4、@CacheEvict注解

該注解的作用根據(jù)指定的key或者是allEntries屬性值移除緩存中特性的鍵值對(duì)。

/* * @Author crush * @CacheEvict 緩存清除 * 可以通過(guò)key 來(lái)指定 要清除的值. * allEntries =true 指定清除這個(gè)緩存中的所有數(shù)據(jù) * beforeInvocation =false * 默認(rèn)代表緩存清除操作是在方法執(zhí)行之后清除 如果出現(xiàn)異常 緩存就不會(huì)清除 * * beforeInvocation =true * 緩存的清除是否在方法之前執(zhí)行 無(wú)論方法是否出現(xiàn)異常 緩存都清除 **/

案例:

@CacheEvict(/*value = "userInfo",*/ key = "#user_id") public void delete(Integer user_id) {System.out.println("刪除了" + user_id + "用戶(hù)"); }

5、@Caching注解

該注解是一個(gè)分組注解,作用是可以同時(shí)應(yīng)用多個(gè)其他注解,該注解提供了3個(gè)屬性cacheable,put,evict分別用于組合@Cacheable、@CachePut、@CacheEvict三個(gè)注解

/* * @Author crush * 這個(gè)就是一個(gè)組合的 **/ @Caching(cacheable = {@Cacheable(/*value = "userInfo",*/key = "#user_name")},put = {@CachePut(/*value = "userInfo",*/key = "#result.user_id"),@CachePut(/*value = "userInfo",*/key = "#result.user_password")} ) public UserInfo selectByUserName(String user_name) {return userInfoMapper.selectByUserName(user_name); }

springboot-cache 使用

步驟:

1、環(huán)境搭建:

DROP TABLE IF EXISTS `t_user`; CREATE TABLE `t_user` (`user_id` varchar(12) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '編號(hào)',`user_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶(hù)名',`user_password` varchar(12) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密碼',PRIMARY KEY (`user_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;INSERT INTO `t_user` VALUES ('1', 'crush', '456789'); INSERT INTO `t_user` VALUES ('2', 'hehe', '456789');

2、導(dǎo)入pom依賴(lài)

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId> </dependency>

3、項(xiàng)目結(jié)構(gòu)

4、pojo層UserInfo類(lèi)

import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors;import java.io.Serializable;/*** @version 1.0* @author: crush* @date: 2021-04-10 16:21*/ @Data @AllArgsConstructor @NoArgsConstructor @Accessors(chain = true) // lombok 注解 寫(xiě)習(xí)慣了 寫(xiě)了這個(gè)注解可以鏈?zhǔn)綄?xiě) // UserInfo userInfo = new UserInfo(); // userInfo.setUser_id("123").setUser_name("crush").setUser_password("abcdefg"); public class UserInfo implements Serializable {private String user_id;private String user_name;private String user_password; }

5、yaml配置文件:

server:port: 8787 spring:datasource:type: com.alibaba.druid.pool.DruidDataSource #ali的數(shù)據(jù)源driver-class-name: com.mysql.cj.jdbc.Driverdruid:username: rootpassword: 123456url: jdbc:mysql://localhost:3306/studentdb?serverTimezone=UTC&useSSL=false&characterEncoding=utf8&serverTimezone=GMT mybatis:type-aliases-package: com.crush.pojomapper-locations: classpath:mapper/*.xml # configuration: # use-actual-param-name: true 駝峰命名

6、mapper層:

@Mapper public interface UserInfoMapper {@Select("select * from t_user where user_id=#{user_id}")UserInfo selectByUserId(String user_id);@Update("UPDATE t_user SET user_name=#{user_name},user_password=#{user_password} WHERE user_id=#{user_id}")int updateUser(UserInfo userInfo);@Select("select * from t_user where user_name=#{user_name}")UserInfo selectByUserName(String user_name); }

7、service和serviceImpl

package com.crush.service;import com.crush.mapper.UserInfoMapper; import com.crush.pojo.UserInfo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.*; import org.springframework.stereotype.Service;/*** @version 1.0* @author: crush* @date: 2021-04-10 16:52*/ @CacheConfig(cacheNames = "userInfo") /* 在類(lèi)上 可以定義一個(gè)公共的配置*/ @Service public class UserInfoService {@AutowiredUserInfoMapper userInfoMapper;/** @Author crush* 原理:* 1 自動(dòng)配置類(lèi) :CacheAutoConfiguration* 2 緩存配置類(lèi)* 3 哪個(gè)配置類(lèi)生效* 4 給容器內(nèi)注冊(cè)了一個(gè)CacheManager:ConcurrentMapCacheManager* 5 可以獲取何創(chuàng)建ConcurrentMapCacheManager 類(lèi)型的緩存組件 他的作用就是講數(shù)據(jù)保存在ConcureentMapzhp* 運(yùn)行流程:* @Cacheable* 1 方法執(zhí)行之前 先去查詢(xún)Cache (緩存組件) 按照cacheNames 指定的名字獲取* 先去獲取相應(yīng)的緩存 第一次獲取緩存如果沒(méi)有 Cache組件會(huì)自動(dòng)創(chuàng)建* 2 去Cache 中查找緩存的內(nèi)容 使用一個(gè)key 默認(rèn)就是方法的參數(shù)* 3 沒(méi)有查到就返回結(jié)果* 4 將目標(biāo)方法返回的結(jié)果 放進(jìn)緩存中** @Cacheable 標(biāo)注的方法 執(zhí)行之前 先來(lái)檢查緩存中有沒(méi)有這個(gè)數(shù)據(jù) 默認(rèn)按照參數(shù)的值作為key去查詢(xún)緩存* 如果沒(méi)有就運(yùn)行方法并將結(jié)果放入緩存** 屬性:* cacheNames :指定緩存組的名字* key:緩存數(shù)據(jù)用的key 默認(rèn)的key是根據(jù)參數(shù)值生成,如果存在 直接返回緩存中的值,否則執(zhí)行該方法,并將返回值保存到緩存中* keyGenerator : 也可以用這個(gè)自定義key的值** condition: 指定符合條件下菜緩存 condition="#id>0"* // #a0> 1 表示第一個(gè)參數(shù)大與1* unless:否定緩存* unless="#a0==2" 如果第一個(gè)參數(shù)是2 就不緩存* sync:是否使用異步模式**/@Cacheable(/*cacheNames = "userInfo",*/key = "#user_id"/*,condition = "#id=1"*/) // #a0> 1 表示第一個(gè)參數(shù)大與1public UserInfo selectByUserId(String user_id) {System.out.println("根據(jù)id查詢(xún)用戶(hù)");return userInfoMapper.selectByUserId(user_id);}/** @Author crush* @CachePut 即調(diào)用方法 有更新緩存數(shù)據(jù)* 運(yùn)行時(shí)機(jī):* 1 先調(diào)用目標(biāo)方法* 2 將目標(biāo)方法的結(jié)果緩存起來(lái)* 測(cè)試:* 1 先去查詢(xún)* 2 然后再更新* 3 然后再執(zhí)行查詢(xún) 發(fā)現(xiàn)還是更新之前的數(shù)據(jù)* 4 發(fā)現(xiàn)他們緩存的時(shí)候 使用的key 是不一樣的 這個(gè)時(shí)候要使用相同的key***/@CachePut(/*value = "userInfo", */key = "#userInfo.user_id")public UserInfo updateUser(UserInfo userInfo) {System.out.println("更新用戶(hù)信息");userInfoMapper.updateUser(userInfo);return userInfo;}/** @Author crush* @CacheEvict 緩存清除* 可以通過(guò)key 來(lái)指定 要清除的值.* allEntries =true 指定清除這個(gè)緩存中的所有數(shù)據(jù)* beforeInvocation =false* 默認(rèn)代表緩存清除操作是在方法執(zhí)行之后清除 如果出現(xiàn)異常 緩存就不會(huì)清除* 這句話的意思是 如果這個(gè)方法執(zhí)行時(shí)出現(xiàn)異常 緩存就不會(huì)清除** beforeInvocation =true* 緩存的清除是否在方法之前執(zhí)行 無(wú)論方法是否出現(xiàn)異常 緩存都清除**/@CacheEvict(/*value = "userInfo",*/ key = "#user_id")public void delete(Integer user_id) {System.out.println("刪除了" + user_id + "用戶(hù)");}/** @Author crush* 這個(gè)就是一個(gè)組合的**/@Caching(cacheable = {@Cacheable(/*value = "userInfo",*/key = "#user_name")},put = {@CachePut(/*value = "userInfo",*/key = "#result.user_id"),@CachePut(/*value = "userInfo",*/key = "#result.user_password")})public UserInfo selectByUserName(String user_name) {return userInfoMapper.selectByUserName(user_name);} }

8、Controller層

import com.crush.pojo.UserInfo; import com.crush.service.UserInfoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController;/*** @version 1.0* @author: crush* @date: 2021-04-10 16:20*/ @RestController public class HelloRedisController {@AutowiredUserInfoService userInfoService;@GetMapping("users/{user_id}")public UserInfo user(@PathVariable("user_id") String user_id) {return userInfoService.selectByUserId(user_id);}@GetMapping("users")public UserInfo update(UserInfo userInfo) {UserInfo userInfo1 = userInfoService.updateUser(userInfo);return userInfo1;}@GetMapping("dteUsers/{user_id}")public String delete(@PathVariable("user_id") Integer user_id) {userInfoService.delete(user_id);return "刪除成功";}@GetMapping("usersName/{user_name}")public UserInfo selectByName(@PathVariable("user_name") String user_name) {return userInfoService.selectByUserName(user_name);}}

9、主啟動(dòng)類(lèi):

import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching;@SpringBootApplication @EnableCaching @MapperScan("com.crush.mapper") public class SpringbootRedisApplication {public static void main(String[] args) {SpringApplication.run(SpringbootRedisApplication.class, args);} }

測(cè)試:

@Cacheable 測(cè)試

第一次測(cè)試查詢(xún):

第二次執(zhí)行查詢(xún)方法

@CachePut 測(cè)試

執(zhí)行更新用戶(hù)方法

執(zhí)行完更新用戶(hù)方法之后 再次執(zhí)行 查詢(xún)方法 看控制臺(tái)會(huì)不會(huì)有輸出

@CachePut 測(cè)試

進(jìn)行第二次測(cè)試 再次執(zhí)行查詢(xún)方法 發(fā)現(xiàn)控制臺(tái)沒(méi)有輸出

總結(jié)

以上是生活随笔為你收集整理的springboot-cache的简单使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。