隔着超薄肉丝进入小说_男女刺激性视频大片_女教师的诱波多野结衣_一级欧美过瘾大片

當前位置: 首頁 / 技術干貨 / 正文
旭哥帶你8分鐘學會SpringBoot整合Redis來實現緩存技術

2022-11-02

配置 redis 開發

  1.概述

  隨著互聯網技術的發展,對技術要求也越來越高,所以在當期情況下項目的開發中對數據訪問的效率也有了很高的要求,所以在項目開發中緩存技術使用的也越來越多,因為它可以極大的提高系統的訪問速度,關于緩存的框架也種類繁多,比如 Redis、Ehchahe、JBoss Cache、Voldemort、Cacheonix 等等,今天主要介紹的是使用現在非常流行的 NoSQL 數據庫(Redis)來實現我們的緩存需求

  2.SpringBoot 簡介

  Spring Boot 是由 Pivotal 團隊提供的全新框架,其設計目的是用來簡化新Spring 應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。通過這種方式,Spring Boot 致力于在蓬勃發展的快速應用開發領域(rapid application development)成為領導者。

  主要特點:

  1.創建獨立的 Spring 應用程序

  2.嵌入的 Tomcat,無需部署 WAR 文件

  3.簡化 Maven 配置

  4.自動配置 Spring

  5.提供生產就緒型功能,如指標,健康檢查和外部配置

  6.絕對沒有代碼生成和對 XML 沒有要求配置

  3.Redis 簡介

  Redis 是一個開源(BSD 許可)的,內存中的數據結構存儲系統,它可以用作數據庫、緩存和消息中間件,Redis 的優勢包括它的速度、支持豐富的數據類型、操作原子性,以及它的通用性。

  4.下面就是 SpringBoot 整合 Redis 具體實現步驟

  4.1 springBoot整合redis的實現步驟

  步驟一: 導入相關依賴

  在 Maven 的 pom.xml 文件中加入 Redis 包.配置redis依賴

<!—配置 redis 依賴-->

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.2</version>
</dependency>
//依賴解釋
Spring-data-redis提供了在Spring應用中通過簡單的配置訪問redis服務,
RedisTemplate對reids底層開發包(Jedis, JRedis, and RJC,lettuce)進行了高度封裝,
封裝了 RedisTemplate 對象來進行對Redis的各種操作、異常處理及序列化,支持發布訂閱,并對Spring 3.1 cache進行了實現,它支持所有的Redis原生的 API。

  步驟二: 配置全局配置文件.配置連接redis的連接參數

server:
port: 80
spring:
cache:
type: redis
redis:
# redis數據庫索引(默認為0),我們使用索引為3的數據庫,避免和其他數據庫沖突
#database: 3
# redis服務器地址(默認為loaclhost)
host: localhost
# redis端口(默認為6379)
port: 6379
# redis訪問密碼(默認為空)
#password: pwd123
# redis連接超時時間(單位毫秒)
timeout: 3000
# redis連接池配置
pool:
# 最大可用連接數(默認為8,負數表示無限)
max-active: 8
# 最大空閑連接數(默認為8,負數表示無限)
max-idle: 4
# 最小空閑連接數(默認為0,該值只有為正數才有用)
min-idle: 0
# 從連接池中獲取連接最大等待時間(默認為-1,單位為毫秒,負數表示無限)
max-wait: -1

  步驟三: RedisTemplate模板類對象可以配置,也可以不用配置

  回顧redis存儲的數據類型,五種值的數據類型,最終以字符串類型的數據存到redis里面.

  問題: 向redis存儲javaBean, 集合數據等等其他數據.

  解決方案:

  可以將javaBean, 集合數據等等其他數據轉成字符串類型的數據,再存儲到redis里面.

  具體實現:

  springBoot整合redis時,默認使用的JDK序列化類,將對象數據轉成string類型數據.(可以不用配置RedisTemplate模板類)

  當然可以手動配置RedisTemplate模板類,可以指定序列化類,比如:性能好的JacksonJsonRedisSerializer

  可以不用配置, SpringBoot會掃描到該RedisTemplate會初始化這個bean,存到spring容器中.

  可以配置RedisTemplate(固定代碼)

@Configuration
public class RedisConfig {
/**
* 設置Redis序列化方式,默認使用的JDKSerializer的序列化方式,效率低,這里我們使用 jackson
*
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
//創建模板類對象
RedisTemplate<String, Object> template = new RedisTemplate<>();
//創建String序列化類
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
//指定使用jackson工具負責具體的序列化操作
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//創建jackson的核心api的 ObjectMapper ,將bean,list,map,數組等等轉成字符串
ObjectMapper om = new ObjectMapper();
//使用objectmapper設置bean的屬性,修飾符
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//設置默認類型
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//設置將本地時間轉成字符串
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
//將核心api objectmapper設置給jackson
jackson2JsonRedisSerializer.setObjectMapper(om);
//通過工廠得到連接對象
template.setConnectionFactory(factory);
//設置key序列化方式: 轉成字符串
template.setKeySerializer(redisSerializer);
//設置value序列化: 字符串
template.setValueSerializer(jackson2JsonRedisSerializer);
//value hashmap序列化
template.setHashValueSerializer(jackson2JsonRedisSerializer);
return template;
}

//獲取緩存管理器對象:管理緩存
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解決查詢緩存轉換異常的問題
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解決亂碼的問題),過期時間600秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}

}

  步驟三: 可以測試

  在測試類里面,注入@RedisTemplate操作redis數據庫.

package com.user;

import com.system.SpringApplicationConfig11;
import com.system.user.domain.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Set;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SpringApplicationConfig11.class})
public class DemoRedisTemplate {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Test// hash類型: key-value(key-value)就是map
public void testX9(){
redisTemplate.boundHashOps("myhash").put("username","jack");
redisTemplate.boundHashOps("myhash").put("password","1111");
Set<Object> myhash = redisTemplate.boundHashOps("myhash").keys();
System.out.println("獲取map的所有key:");
for (Object key : myhash) {
System.out.print(key+",");
}
System.out.println();
List<Object> myhash1 = redisTemplate.boundHashOps("myhash").values();
System.out.println("獲取map的所有value");
for (Object value : myhash1) {
System.out.print(value+",");
}
System.out.println();
}
@Test//sortedset類型: redisTemplate
public void testX8(){
redisTemplate.boundZSetOps("myset2withscore").add("jack",10.0);
redisTemplate.boundZSetOps("myset2withscore").add("rose",9.0);
redisTemplate.boundZSetOps("myset2withscore").add("ship",20.0);
Set<Object> myset2withscore = redisTemplate.boundZSetOps("myset2withscore").range(0, -1);
for (Object o : myset2withscore) {
System.out.println(o);
}
}
@Test//set類型: redisTemplate
public void testX7(){
redisTemplate.boundSetOps("myset1noscore").add("jack");
redisTemplate.boundSetOps("myset1noscore").add("jack");
redisTemplate.boundSetOps("myset1noscore").add("rose");
Set<Object> myset1noscore = redisTemplate.boundSetOps("myset1noscore").members();
for (Object o : myset1noscore) {
System.out.println(myset1noscore);
}

}
@Test//list類型的數據: ListOperations
public void testX5(){
Boolean flag = redisTemplate.hasKey("mylist");//判斷緩存數據庫是否有這個key
System.out.println("mylist:"+flag);
Boolean flag2 = redisTemplate.hasKey("username");//判斷緩存數據庫是否有這個key
System.out.println("username:"+flag2);

}
@Test//list類型的數據: RedisTemplate
public void testX6(){
redisTemplate.boundListOps("mylist").leftPush("jack");
redisTemplate.boundListOps("mylist").leftPush("rose");
redisTemplate.boundListOps("mylist").rightPush("ship");
List<Object> mylist = redisTemplate.boundListOps("mylist").range(0, -1);
for (Object o : mylist) {
System.out.println(o);
}

}
@Test//list類型的數據: ListOperations
public void testX4(){
redisTemplate.opsForList().leftPush("mylist","jack");
Object mylist = redisTemplate.opsForList().leftPop("mylist");
System.out.println(mylist);
//ListOperations<String, Object> operation= redisTemplate.opsForList();

}

@Test//操作string
public void testX(){
redisTemplate.opsForValue().set("username","jack");//底層用的就是jedis
Object username = redisTemplate.opsForValue().get("username");
System.out.println(username);
}
@Test//操作string
public void testX2(){
redisTemplate.boundValueOps("username").set("rose");//向緩存中設置數據
Object username = redisTemplate.boundValueOps("username").get();
System.out.println(username);
}
@Test//操作string
public void testX3(){
User user2 = new User(10L,"大馬猴","dmh@sina.com","666","12");
//底層: 用指定的Jackson2JsonRedisSerializer的objectMapper將user轉成json,設置到緩存中
redisTemplate.boundValueOps("user").set(user2);

}


}

  RedisTemplate 核心api:

  RedisTemplate概述:

  RedisTemplate 是 Spring Boot 訪問 Redis 的核心組件,底層通過 RedisConnectionFactory 對多種 Redis 驅動進行集成,上層通過 XXXOperations 提供豐富的 [API],操作redis數據庫.

  問題:

  但美中不足的是,需要針對應用場景,使用不同的 RedisSerializer 對RedisTemplate 進行定制,那有沒有一種方法能夠自動完成 RedisTemplate 的定義呢?

  解決方案:

  自己配置RedisTemplate,手動指定序列化類.

image-20220918160407533

  連接池自動管理,提供了一個高度封裝的“RedisTemplate”類(會自動初始化到容器中,可以直接使用)。

  RedisTemplate默認使用的jdk的序列化

  當然也可以指定RedisTemplate的序列化工具

  針對jedis客戶端中大量api進行了歸類封裝,將同一類型操作封裝為operation操作接口。

  操作不同的數據類型,獲取不同的operations操作對象.

  Jedis的api:

  ValueOperations:操作的string類型的數據, 簡單K-V操作,底層就是set方法

  SetOperations:set類型數據操作.

  ZSetOperations:zset類型數據操作

  HashOperations:針對map類型的數據操作

  ListOperations:針對list類型的數據操作

  提供了對key的“bound”(綁定)便捷化操作API,可以通過bound封裝指定的key,然后進行一系列的操作而無須“顯式”的再次指定Key,即BoundKeyOperations將事務操作封裝,由容器控制。

  BoundValueOperations

  底層封裝的就是ValueOperations:操作的string類型的數據, 簡單K-V操作,底層就是set方法

  BoundSetOperations

  底層封裝的就是SetOperations:set類型數據操作.

  BoundListOperations

  底層封裝的就是ZSetOperations:zset類型數據操作

  BoundSetOperations

  底層封裝的就是ZSetOperations:zset類型數據操作

  BoundHashOperations

  底層封裝的就是HashOperations:針對map類型的數據操作

  針對數據的“序列化/反序列化”,提供了多種可選擇策略(RedisSerializer)

  JdkSerializationRedisSerializer:POJO對象的存取場景,使用JDK本身序列化機制,將pojo類通過ObjectInputStream/ObjectOutputStream進行序列化操作,最終redis-server中將存儲字節序列。是目前最常用的序列化策略。

  缺點: 性能差,不能對本地日期類型進行轉換.

  StringRedisSerializer:Key或者value為字符串的場景,根據指定的charset對數據的字節序列編碼成string,是“new String(bytes, charset)”和“string.getBytes(charset)”的直接封裝。是最輕量級和高效的策略。

  JacksonJsonRedisSerializer:jackson-json工具提供了javabean與json之間的轉換能力,可以將pojo實例序列化成json格式存儲在redis中,也可以將json格式的數據轉換成pojo實例。因為jackson工具在序列化和反序列化時,需要明確指定Class類型,因此此策略封裝起來稍微復雜。【需要jackson-mapper-asl工具支持】

  OxmSerializer:提供了將javabean與xml之間的轉換能力,目前可用的三方支持包括jaxb,apache-xmlbeans;redis存儲的數據將是xml工具。不過使用此策略,編程將會有些難度,而且效率最低;不建議使用。【需要spring-oxm模塊的支持】

  如果你的數據需要被第三方工具解析,那么數據應該使用StringRedisSerializer而不是JdkSerializationRedisSerializer。

  注意小結:

  如果向緩存中添加javaBean對象時,一定要讓javaBean實現Serializable 接口

  4.2 Service 層應用緩存之springBoot整合緩存

  為什么要springBoot整合緩存Cache.

  通過Cache保存數據, 提高數據的響應效率.

  實現本質:

  第一步: 第一次需要從關系型數據庫里面把數據查詢查詢出來, 設置到緩存中

  第二步: 下次再查詢數據時,不在查詢關系型數據庫中,而是從緩存中取出數據

  存在問題:

  比如: 第一次從mysql中查詢了100條數據,存到緩存中有100條數據

  比如: 下次再查詢之前,刪除了一條數據,mysql剩余99條數據, 緩存中依然了100條數據

  解決方案:

  如果關系型數據庫中的數據發生了變化,需要同步更新緩存數據(讓關系型數據庫的數據與redis緩存的數據同步)

  在企業中解決方案:

  解決方案一: 通過手寫緩存代碼,實現緩存數據的存取以及緩存數據的同步更新(代碼冗余)

  解決方案二: 通過springBoot整合緩存,實現緩存數據的自動存儲,以及自動同步更新.

  具體的整合步驟:

  緩存常用的注解

  @Cacheable: 先從緩存中查詢數據,如果緩存中沒有數據,這時從關系型數據庫查詢數據,設置到緩存中.

  @CachePut: 先從關系型數據庫中查詢數據,清空緩存中的數據,把返回的數據再次設置到緩存中

  實現緩存的同步更新.

  注意細節:

  @CachePut通常操作的添加方法和更新方法

  @CachePut要求緩存的key要保持一致.

  當執行添加一條數據和修改一條數據時,使用@CachePut注解,key使用id

  實現緩存的同步更新

  第一步: 添加id=13L的數據, 設置到緩存中.

  第二步: 修改id=13L的數據, 比如: 修改username=jack, 緩存會自動同步更新為jack.

  @CachePut和@Cacheable一般不建議放在一塊使用.

  @Cacheable和@CachePut一塊使用時,不會實現緩存的同步更新

  解決@Cacheable和@CachePut實現緩存的同步更新,

  第一步: 執行查詢操作,設置10條數據到緩存中

  第二步: 執行添加一條數據操作, 設置1條數據到緩存中,手動更新緩存,實現緩存的同步, 最終緩存了11條數據

  解決方案:

  修改添加方法,將添加方法的返回值與查詢方法的返回值保持一致

  如果不一致,會出現類型轉換異常.

image-20220919163454152

  在添加方法中,執行完添加后,再次查詢數據庫,最終實現緩存的同步

@CachePut(cacheNames = "listA" ,key="'aa'")
public List<User> addUser2(User user){
//1.先添加
userMapper.insert(user);
//2.再查詢
List<User> users = userMapper.selectAll();
return users;
}

  @CacheEvict: 直接清空緩存中的數據

  步驟一: 導入依賴

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

  步驟二: 在引導類上面使用

@SpringBootApplication
@MapperScan("com.dao")
@EnableCaching//開啟緩存支持
public class SpringApplicationConfig {
    public static void main(String[] args){
        //自動掃描包, 自動裝配,啟動tomcat插件
        SpringApplication.run(SpringApplicationConfig.class);
    }
}

  步驟三: 使用緩存注解

@Service
public class TestService {

@Autowired
private PersonRepo personRepo;

/**

* @Cacheable 應用到讀取數據的方法上,先從緩存中讀取,如果沒有再從 DB 獲取數據,然后把數據添加到緩存中

* unless 表示條件表達式成立的話不放入緩存

*/

@Cacheable(value = "user", key = "#root.targetClass + #username", unless = "#result eq null" , condition="") public Person getPersonByName(String username) {

Person person = personRepo.getPersonByName(username); return person;

}

/**


* @CachePut 應用到寫數據的方法上,如新增方法,調用方法時會自動把相應的數據放入緩存,同步更新緩存
為什么沒有更新緩存
因為CachePut是方法運行完成之后然后再往緩存中放入數據,所以使用以下的方式進行操作
這個是以方法的參數ID進行緩存操作,當然還可以使用下面這種方式進行操作。拿出返回值的id。在這里需要注意的一點是Cacheable的key是不能用#result取出對應的返回值的。
*/

@CachePut(value = "user", key = "#person.id", unless = "#person eq null")
public Person savePerson(Person person) {

return personRepo.savePerson(person);

}

/**

* @CacheEvict 應用到刪除或者修改數據的方法上,調用方法時會將指定key的緩存數據清空, 再次重新查詢數據庫

*/

@CacheEvict(value = "user", key = "#root.targetClass + #username", condition = "#result eq true")
public boolean removePersonByName(String username) {

return personRepo.removePersonByName(username) > 0;

}

public boolean isExistPersonName(Person person) {

return personRepo.existPersonName(person) > 0;

}

 

  總結:

  @Cacheable源碼實現

@Cacheable(cacheNames = "listA",key = "'aa'")
public List<User> findUsers(){
List<User> list = userMapper.selectAll();
return list;
}
//源碼(手動整合緩存的話,一般使用Ehcache)
//1.通過緩存管理器得到指定名稱的緩存
Cache cache = cacheManager.getCache("listA");
//2.通過指定名稱: 獲取保存數據的緩存區域
Cache.ValueWrapper cacheValue = cache.get("aa");
if(cacheValue!=null){
//3.根據key從緩存中查詢數據
//3.1 判斷緩存中有沒有數據
//3.2 緩存中有數據,說明不是第一次訪問
Object o = cacheValue.get();
System.out.println(o);
System.out.println("將從緩存中拿出的數據響應到前臺頁面");

}else{
//3.3 緩存中沒有數據,說明是第一次訪問,查詢mysql的數據,存到緩存
List<User> users = userMapper.selectAll();
//3.4 將users集合轉成json,存到緩存中
String json ="";
//將json存到緩存里面

}

  總結

  @Cacheable屬性說明:

  cacheNames/value :用來指定緩存組件的名字

  key :緩存數據時使用的 key,可以用它來指定。默認是使用方法參數的值。(這個 key 你可以使用 spEL 表達式來編寫)

  keyGenerator :key 的生成器。 key 和 keyGenerator 二選一使用, 需要自定義bean生成key

  cacheManager :可以用來指定緩存管理器。從哪個緩存管理器里面獲取緩存。

  condition :可以用來指定符合條件的情況下才緩存

  unless :否定緩存。當 unless 指定的條件為 true ,方法的返回值就不會被緩存。當然你也可以獲取到結果進行判斷。(通過 #result 獲取方法結果)

  sync :是否使用異步模式。

  緩存注解源碼

// @since 3.1 可以標注在方法上、類上 下同
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Cacheable {//緩存查詢 作用: 先查詢緩存,沒有再查詢關系數據庫存到緩存
// 緩存名稱 可以寫多個~
@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};

// 支持寫SpEL,切可以使用#root
String key() default "";
// Mutually exclusive:它和key屬性互相排斥。請只使用一個
String keyGenerator() default "";

String cacheManager() default "";
String cacheResolver() default "";

// SpEL,可以使用#root。 只有true時,才會作用在這個方法上
String condition() default "";
// 可以寫SpEL #root,并且可以使用#result拿到方法返回值~~~
String unless() default "";

// true:表示強制同步執行。(若多個線程試圖為**同一個鍵**加載值,以同步的方式來進行目標方法的調用)
// 同步的好處是:后一個線程會讀取到前一個緩存的緩存數據,不用再查庫了~~~
// 默認是false,不開啟同步one by one的
// @since 4.3 注意是sync而不是Async
// 它的解析依賴于Spring4.3提供的Cache.get(Object key, Callable<T> valueLoader);方法
boolean sync() default false;
}


@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CachePut {//緩存更新: 先查詢數據庫,然后更新緩存

@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};

// 注意:它和上面區別是。此處key它還能使用#result
String key() default "";
String keyGenerator() default "";

String cacheManager() default "";
String cacheResolver() default "";

String condition() default "";
String unless() default "";
}

Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CacheEvict {//緩存清除

@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};

// 它也能使用#result
String key() default "";
String keyGenerator() default "";

String cacheManager() default "";
String cacheResolver() default "";
String condition() default "";

// 是否把上面cacheNames指定的所有的緩存都清除掉,默認false
boolean allEntries() default false;
// 是否讓清理緩存動作在目標方法之前執行,默認是false(在目標方法之后執行)
// 注意:若在之后執行的話,目標方法一旦拋出異常了,那緩存就清理不掉了~~~~
boolean beforeInvocation() default false;

}

  spEL 編寫 key或者condition或者unless屬性,可以使用下面的對象

  注意: key屬性里面,可以使用下面圖片的對象, condition屬性不能全部使用下面圖片的對象, unless也一樣

  @Cacheable的condition 屬性能使用的SpEL語言只有#root和獲取參數類的SpEL表達式,不能使用返回結果的#result 。所以 condition = "#result != null" 會導致所有對象都不進入緩存,每次操作都要經過數據庫。

  @Cacheable的unless屬性可以使用#result表達式。 效果: 緩存如果有符合要求的緩存數據則直接返回,沒有則去數據庫查數據,查到了就返回并且存在緩存一份,沒查到就不存緩存。

image-20220918212534454

  4.3 數據訪問資源類

@Component
@Path("personMgr")
public class PersonMgrResource {

@Autowired
private PersonService personService;

@GET
@Path("getPersonByName")
@Produces(MediaType.APPLICATION_JSON)
public JsonResp getPersonByName(@QueryParam("username") String username) {

Person person = personService.getPersonByName(username);

return JsonResp.success(person);

}

@POST
@Path("removePersonByName")
@Produces(MediaType.APPLICATION_JSON)
public JsonResp removePersonByName(@QueryParam("username") String username) {

if(personService.removePersonByName(username)) {

return JsonResp.success();

}

return JsonResp.fail("系統錯誤!");

}

@POST
@Path("savePerson")
@Produces(MediaType.APPLICATION_JSON)
public JsonResp savePerson(Person person) {

if (personService.isExistPersonName(person)) {

return JsonResp.fail("用戶名已存在!");

}

if (personService.savePerson(person).getId() > 0) {

return JsonResp.success();
}

return JsonResp.fail("系統錯誤!");

}

}

  5.通過 postman 工具來測試緩存是否生效

  第一次訪問查找用戶:

  第一次通過用戶名稱來查找用戶可以看到是從庫中查詢的數據,我們可以通過 RedisClient 工具來查看數據已放入了緩存

  第二次查找用戶:發現服務端并未打印任何數據庫查詢日志,可以知道第二次查詢是從緩存中查詢得到的數據。

  總結

  本文介紹如何通過 SpringBoot 來一步步集成 Redis 緩存,關于 Redis 的使用它不僅可以用作緩存,還可以用來構建隊列系統,Pub/Sub 實時消息系統,分布式系統的的計數器應用,關于 Redis 更多的介紹,請前往官網查閱。

好程序員公眾號

  • · 剖析行業發展趨勢
  • · 匯聚企業項目源碼

好程序員開班動態

More+
  • HTML5大前端 <高端班>

    開班時間:2021-04-12(深圳)

    開班盛況

    開班時間:2021-05-17(北京)

    開班盛況
  • 大數據+人工智能 <高端班>

    開班時間:2021-03-22(杭州)

    開班盛況

    開班時間:2021-04-26(北京)

    開班盛況
  • JavaEE分布式開發 <高端班>

    開班時間:2021-05-10(北京)

    開班盛況

    開班時間:2021-02-22(北京)

    開班盛況
  • Python人工智能+數據分析 <高端班>

    開班時間:2021-07-12(北京)

    預約報名

    開班時間:2020-09-21(上海)

    開班盛況
  • 云計算開發 <高端班>

    開班時間:2021-07-12(北京)

    預約報名

    開班時間:2019-07-22(北京)

    開班盛況
IT培訓IT培訓
在線咨詢
IT培訓IT培訓
試聽
IT培訓IT培訓
入學教程
IT培訓IT培訓
立即報名
IT培訓

Copyright 2011-2023 北京千鋒互聯科技有限公司 .All Right 京ICP備12003911號-5 京公網安備 11010802035720號