一篇掌握SpringBoot+SpringCache+Redis超詳細例項
1、建立maven專案
2、pom檔案
<?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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>springWithRedis</artifactId>
<version>1.0-SNAPSHOT</version><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>8</source><target>8</target></configuration></plugin></plugins></build>
<dependencies>
<!-- lombok依賴 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
<!-- spring整合redis依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
<!-- spring依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.2.8.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2、application.properties 配置檔案
# Redis資料庫索引(預設為0)
spring.redis.database=0
# Redis伺服器地址
spring.redis.host=**********
#配置快取相關
cache.default.expire-time=20000
cache.user.expire-time=1800
cache.user.name=suiyiqi
3、實體類
package com.cache.redis.entity;
import lombok.Data;
import java.io.Serializable;
/**
* @author 一抹餘陽
*/
@Data
// 物件要序列化,不然可能會出現亂碼
public class UserInfo implements Serializable {
private String id;
private String nickName;
}
4、service
package com.cache.redis.service;
import com.cache.redis.entity.UserInfo;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import java.util.List;
/**
* @author 一抹餘陽
*/
// @CacheConfig:定義公共設定
@CacheConfig(cacheNames="userInfo2")
public interface UserInfoService {
// 1、@Cacheable:定義快取,用於觸發快取.
// 該註解用於標註於方法之上用於標識該方法的返回結果需要被快取起來,
// 標註於類之上標識該類中所有方法均需要將結果快取起來。
// 該註解標註的方法每次被呼叫前都會觸發快取校驗,
// 校驗指定引數的快取是否已存在(已發生過相同引數的呼叫),
// 若存在,直接返回快取結果,否則執行方法內容,最後將方法執行結果儲存到快取中。
// 2、key:用於指定當前方法的快取儲存時的鍵的組合方式,
// 預設的情況下使用所有的引數組合而成,這樣可以有效區分不同引數的快取。
// 當然我們也可以手動指定,指定的方法是使用SPEL表示式。
// #root.methodName -> 即為用當前方法名稱做為key
// #id -> 即為用入參名稱id作為key
// #userInfo.id -> 即為用UserInfo物件的id屬性作為key
// 3、 @Cacheable(cacheNames = "userInfo",key = "#id"),cacheNames也可以單獨指定
// 4、鍵值對快取key,就是說redis快取的時候key的生成時如下格式:value::key 或 cacheNames::key
// 例如,指定value或cacheNames為 userInfo2,key為1,
// 即 @Cacheable(value="userInfo2",key="1") 或 @Cacheable(cacheNames = "userInfo",key = "#id")
// 生成的快取key值為 userInfo2::1
@Cacheable(key = "#root.methodName")
List<UserInfo> findAll();
// @CachePut:定義更新快取,觸發快取更新
@Cacheable(key = "#id")
UserInfo findById(String id);
// @CachePut:該註解用於更新快取,無論結果是否已經快取,
// 都會在方法執行結束插入快取,相當於更新快取,一般用於更新方法之上。
@CachePut(key = "#userInfo.id")
UserInfo saveUserInfo(UserInfo userInfo);
// @CacheEvict:該註解主要用於刪除快取操作
// allEntries=true:刪除所有快取
// @CacheEvict(key = "#id") 刪除id為某值的快取
@CacheEvict(allEntries=true)
void delUserInfo(String id);
// 擴充套件:condition屬性是用來指定判斷條件從而確定是否生成快取
// @Cacheable(value = "userInfo2",key = "#id",condition="#id%2 == 0")
// 如果id%2 == 0判斷條件成立的話,將會生成redis快取,即返回true時生成Redis快取,
// 如果EL表示式返回false的話則不生成快取
}
5、service實現類
package com.cache.redis.service.impl;
import com.cache.redis.entity.UserInfo;
import com.cache.redis.service.UserInfoService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @author 一抹餘陽
* 全部直接模擬資料庫操作,省掉dao層,如果需要可以自行新增
*/
@Service
public class UserInfoServiceImpl implements UserInfoService {
@Override
public List<UserInfo> findAll() {
System.out.println("查了全部資料。。。");
UserInfo userInfo = new UserInfo();
userInfo.setId("200");
userInfo.setNickName("搬磚小能手");
UserInfo userInfo2 = new UserInfo();
userInfo2.setId("300");
userInfo2.setNickName("我是誰");
List<UserInfo> userInfoList = new ArrayList<>();
userInfoList.add(userInfo);
userInfoList.add(userInfo2);
return userInfoList;
}
@Override
public UserInfo findById(String id) {
System.out.println("查了一次資料庫。。。");
UserInfo userInfo = new UserInfo();
if("100".equals(id)){
userInfo.setNickName("呵呵");
userInfo.setId("100");
}else{
userInfo.setNickName("哈哈");
userInfo.setId("101");
}
return userInfo;
}
@Override
public UserInfo saveUserInfo(UserInfo userInfo) {
System.out.println("新增或者修改了一次資料。。。");
return userInfo;
}
@Override
public void delUserInfo(String id) {
System.out.println("刪除了一個資料。。。");
}
}
6、redisconfig類
package com.cache.redis.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @author 一抹餘陽
* @create 2020-09-25 10:25
*/
@Configuration //@Configuration:專案啟動配置註解
@EnableCaching //@EnableCaching:開啟快取功能
public class RedisConfig {
//@ 讀取 application.properties 配置的值
@Value("${cache.default.expire-time}")
private int defaultExpireTime;
@Value("${cache.user.expire-time}")
private int userCacheExpireTime;
@Value("${cache.user.name}")
private String userCacheName;
/**
* 快取管理器
* @param lettuceConnectionFactory
* @return
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory lettuceConnectionFactory) {
RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig();
// 設定快取管理器管理的快取的預設過期時間
defaultCacheConfig = defaultCacheConfig.entryTtl(Duration.ofSeconds(defaultExpireTime))
// 設定 key為string序列化
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
// 設定value為json序列化
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
// 不快取空值
.disableCachingNullValues();
Set<String> cacheNames = new HashSet<>();
cacheNames.add(userCacheName);
// 將需要不同過期時間 cacheNames 配置
// 對每個快取空間應用不同的配置,如果所有cacheNames的過期時間都一直,則則不需要特殊配置
Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
configMap.put(userCacheName, defaultCacheConfig.entryTtl(Duration.ofSeconds(userCacheExpireTime)));
RedisCacheManager cacheManager = RedisCacheManager.builder(lettuceConnectionFactory)
.cacheDefaults(defaultCacheConfig)
.initialCacheNames(cacheNames)
.withInitialCacheConfigurations(configMap)
.build();
return cacheManager;
}
}
7、啟動類
package com.cache.redis;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
/**
* @author 一抹餘陽
*/
@SpringBootApplication
@PropertySources(value = {@PropertySource(value = {"classpath:application.properties"}, encoding = "utf-8")
})
@Slf4j
public class App {
/**
* 啟動方法
* @param args
*/
public static void main(String[] args) {
log.info("ApiMain begin...");
try {
SpringApplication.run(App.class, args);
log.info("App run sucessful!");
} catch (Throwable throwable) {
log.error("App run error!error msg is {}", throwable.getMessage(), throwable);
}
}
}
8、測試類
import com.cache.redis.App;
import com.cache.redis.entity.UserInfo;
import com.cache.redis.service.UserInfoService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.util.List;
/**
* @author 一抹餘陽
* redis快取測試
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
public class CacheTest {
@Resource
UserInfoService userInfoService;
@Test
public void findAll(){
// 測試快取:
// 第一次查詢:沒有快取會先模擬查詢資料庫 列印 查了全部資料。。。
// 然後列印查到的資料
// 第二次查詢:快取裡有資料,會直接列印快取的資料
List<UserInfo> all = userInfoService.findAll();
System.out.println(all);
}
@Test
public void queryUserInfo(){
// 第一次查詢:沒有快取資料會先模擬查詢資料庫 列印 查了一次資料庫。。。
// 然後列印模擬查詢的資料
UserInfo user = userInfoService.findById("100");
System.out.println(user);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 第二查詢:快取中有資料,會直接從快取中查詢到資料直接列印,不去模擬資料庫查詢操作
UserInfo user2 = userInfoService.findById("100");
System.out.println(user2);
}
@Test
public void delUserINfo(){
// 如 queryUserInfo() ,快取中有資料則直接返回快取中資料,沒有模擬查詢資料庫
UserInfo user = userInfoService.findById("100");
System.out.println(user);
// 刪除掉快取中 id為100 的資料
userInfoService.delUserInfo("100");
// 再次查詢則還需要模擬資料庫查詢操作
UserInfo user2 = userInfoService.findById("100");
System.out.println(user2);
}
@Test
public void saveOrUpdateUserInfo(){
// 不論快取中有沒有資料,都去模擬資料庫操作,更新userInfo.id為100的到快取
UserInfo userInfo = new UserInfo();
userInfo.setNickName("嘎嘎");
userInfo.setId("100");
UserInfo userInfo2 = userInfoService.saveUserInfo(userInfo);
System.out.println("修改後的資料" + userInfo2);
}
}
9、專案架構截圖
相關文章
- php curl選項列表(超詳細)PHP
- 動態VLAN詳細配置例項
- SwiftUI 官方畫圖例項詳細解析SwiftUI
- mysql分割槽功能、例項詳細介紹MySql
- 【超詳細】Linux常用命令,這些你需要掌握!Linux
- Spring中Bean的例項化詳細流程SpringBean
- A*演算法(超級詳細講解,附有舉例的詳細手寫步驟)演算法
- 基於QT錄製PCM音訊例項詳細QT音訊
- Spring BeanFactory例項化Bean的詳細過程SpringBean
- ASP做paypal支付介面詳細程式碼和例項
- JWT 超詳細分析JWT
- Linux Awk 內建函式詳細介紹(例項)Linux函式
- GitHub和Git超超超詳細使用教程!Github
- 【Oracle ASM】關於asm例項與db例項中的磁碟狀態_詳細分析過程OracleASM
- Vue 指令大全(超詳細)Vue
- MyBatis Generator 超詳細配置MyBatis
- Vue 超詳細手記Vue
- java運算子(超詳細!!!)Java
- Maven筆記---超詳細Maven筆記
- web259(超詳細)Web
- curl例項詳解
- sudo 詳解+例項
- 掌握企業核心:工商詳細資訊API 60多項全維度資訊解讀API
- 如何反轉連結串列?超詳細圖解,看這一篇就夠了!圖解
- 一次詳細的RAC 節點例項驅逐分析文件
- javaSE綜合例項之記事本詳細解析--長篇(初學者)Java
- 一次RAC例項驅逐詳細分析及解決方案
- iOS超級超級詳細介紹GCDiOSGC
- Go Struct超詳細講解GoStruct
- Redis安裝教程(超詳細)Redis
- 超詳細kafka教程來啦Kafka
- 超詳細 DNS 協議解析DNS協議
- python使用xpath(超詳細)Python
- 超級詳細Tcpdump 的用法TCP
- rman超詳細命令介紹
- 掌握C#中的GUI多執行緒技巧:WinForms和WPF例項詳解C#GUI執行緒ORM
- Spring AOP全面詳解(超級詳細)Spring
- Java註解最全詳解(超級詳細)Java