給接口添加緩存

早期文章
? ? ? ? 在項(xiàng)目中有些接口調(diào)用非常的頻繁,但是接口的數(shù)據(jù)卻很少改變,在接口上添加緩存可以有效的提高接口的性能。本文介紹如何在接口上增加緩存來(lái)提高接口的性能。
一、創(chuàng)建 SpringBoot 項(xiàng)目
? ?? ? ?在項(xiàng)目中,我們通過(guò)引入 Redis 服務(wù)器來(lái)做接口的緩存,我們創(chuàng)建一個(gè) SpringBoot 的項(xiàng)目,先來(lái)添加其依賴(lài),依賴(lài)如下:
<dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-data-redisartifactId>dependency><dependency><groupId>org.apache.commonsgroupId><artifactId>commons-pool2artifactId><version>2.6.0version>dependency>
? ? ? ??依賴(lài)中引入了 Redis 所需的依賴(lài),以及連接池的依賴(lài),引入依賴(lài)后,來(lái)完成相關(guān)的配置。配置文件如下:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghaispring.datasource.username=rootspring.datasource.password=spring.jackson.date-format=yyyy-MM-dd?HH:mm:ssspring.jackson.time-zone=GMT+8mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImplspring.redis.host=127.0.0.1spring.redis.port=6379spring.redis.database=0spring.redis.timeout=1800000spring.redis.lettuce.pool.max-active=20spring.redis.lettuce.pool.max-wait=-1spring.redis.lettuce.pool.max-idle=5spring.redis.lettuce.pool.min-idle=0
二、創(chuàng)建項(xiàng)目的結(jié)構(gòu)及代碼
? ? ? ??寫(xiě)一個(gè)簡(jiǎn)單的 Demo,Demo 的功能有兩個(gè),一個(gè)用來(lái)讀取用戶(hù)的列表,第二個(gè)功能用來(lái)添加新的用戶(hù)。我們首先創(chuàng)建 controller、service 和 mapper 三個(gè)包結(jié)構(gòu)。然后在其下分別添加相關(guān)的代碼。
? ? ? ? 首先添加 controller 的代碼,代碼如下:
public class CacheController{private CacheService cacheService;????public?List?getList() { return cacheService.getList();}public void save(User user) {cacheService.setUser(user);????}}
? ? ? ? 在 Controller 中有 getList 和 save 兩個(gè)方法,getList 方法用來(lái)獲取用戶(hù)的列表,save 用來(lái)添加新的用戶(hù)。然后來(lái)編寫(xiě)這兩個(gè)方法對(duì)應(yīng)的 service 代碼,代碼如下:
public class CacheServiceImpl extends ServiceImpl<UserMapper, User> implements CacheService{????public?List?getList() {return baseMapper.selectList(null);}????public?void?setUser(User?user) {baseMapper.insert(user);}}
? ? ? ? 在 service 的 getList 方法,直接調(diào)用 baseMapper 的 selectList 方法來(lái)獲取全部用戶(hù)的列表,setUser 方法直接調(diào)用 baseMapper 的 insert 方法來(lái)添加新的用戶(hù)。
? ? ? ? mapper 文件直接繼承 BaseMapper 即可,mapper 代碼如下:
public interface UserMapper extends BaseMapper<User>{}
? ? ? ? 上面的代碼是典型 Web 開(kāi)發(fā)的套路。在上面的代碼中,每次調(diào)用 getList 接口都會(huì)查詢(xún) user 表,返回用戶(hù)的列表。在返回的列表中,只要用戶(hù)的信息不變,或者用戶(hù)沒(méi)有增減,那么列表返回的內(nèi)容總是固定的。在這種情況,每次調(diào)用接口都去查詢(xún)數(shù)據(jù)庫(kù),對(duì)數(shù)據(jù)庫(kù)而言是一種負(fù)擔(dān),且是不必要的。這時(shí)候給該接口增加一個(gè)緩存,那么每次調(diào)用 getList 時(shí)就無(wú)需查詢(xún)數(shù)據(jù)庫(kù)了,這樣既減輕了數(shù)據(jù)庫(kù)的壓力,也提升了接口的性能,這樣就非常的 nice 了。
三、給接口增加緩存
? ? ? ? 緩存的形式比較多,可以在項(xiàng)目的內(nèi)存中直接進(jìn)行緩存,也可以使用專(zhuān)門(mén)的緩存服務(wù)器進(jìn)行緩存。如果緩存的內(nèi)容少,可以直接在項(xiàng)目的內(nèi)存中進(jìn)行緩存,省去了緩存服務(wù)器的管理與成本,緩存的內(nèi)容多則在緩存服務(wù)器中進(jìn)行緩存,方便后續(xù)的擴(kuò)容和進(jìn)行單獨(dú)的管理等,并且在項(xiàng)目重啟后,緩存的內(nèi)容不丟。本 Demo 我們使用 Redis 服務(wù)器來(lái)作為緩存。
? ? ? ? 使用緩存,首先來(lái)增加一個(gè) config 包,在包中創(chuàng)建一個(gè) Redis 的配置類(lèi),在該配置類(lèi)中設(shè)置編寫(xiě) key 生成的規(guī)則,設(shè)置 RedisTemplate 的規(guī)則,設(shè)置緩存的規(guī)則等。此處,基本上每個(gè) Redis 的配置類(lèi)都差不多,因此,這里就不貼出具體的代碼了。
? ? ? ? 在配置好 Redis 的配置類(lèi)后,無(wú)需修改任何代碼,只需要在 service 的方法上增加注解,即可給接口增加緩存,增加注解后的 service 代碼如下:
(value = "user", keyGenerator = "keyGenerator")public ListgetList() {return baseMapper.selectList(null);}(value = "user", allEntries = true)public void setUser(User user) {baseMapper.insert(user);}
? ? ? ? 在上面的代碼中,為兩個(gè)方法分別增加了注解。第一個(gè) @Cacheable 注解用于給該方法增加一個(gè)緩存,另外一個(gè) @CacheEvict 注解用于給清除緩存。在兩個(gè)注解中,都有一個(gè) value 值,@CacheEvict 清除緩存時(shí)會(huì)清除指定 value 的緩存。
? ? ??? 增加完緩存后,我們重啟項(xiàng)目,重新來(lái)測(cè)試接口的緩存。在測(cè)試接口之前,不要忘記啟動(dòng) Redis 服務(wù)器,然后通過(guò) redis-cli 執(zhí)行 flushdb 清空 redis 中的緩存,這樣方便我們觀察緩存中的數(shù)據(jù)。做好這些準(zhǔn)備,我們就可以請(qǐng)求接口的地址了,地址如下:
http://localhost:8080/api/user/getList? ? ? ? 請(qǐng)求上面的接口后,在 IDEA 的控制臺(tái)中可以看到接口查詢(xún)數(shù)據(jù)庫(kù)的日志記錄,日志如下圖所示。

? ? ? ? 此時(shí)來(lái)查看 Redis 服務(wù)器緩存,緩存中的內(nèi)容如下圖所示。

? ? ? ? 可以看到,緩存中已經(jīng)有數(shù)據(jù)了,然后再次訪問(wèn)該接口,在 IDEA 的控制臺(tái)中沒(méi)有任何的查詢(xún)?nèi)罩据敵觯墙涌谕瑯臃祷亓藙偛诺臄?shù)據(jù)列表,這樣就說(shuō)明我們接口查詢(xún)的數(shù)據(jù)被緩存到 Redis 中了。
? ? ? ? 當(dāng)我們?cè)黾右粋€(gè)新的 user 記錄時(shí),需要讓緩存失效,也就是刪除緩存。因?yàn)閷?shí)際的用戶(hù)列表發(fā)生了變化,這個(gè)功能由 @CacheEvict 注解為我們完成。我們通過(guò) save 接口來(lái)增加一個(gè)用戶(hù),增加用戶(hù)如下圖。

? ? ? ? 此時(shí)再來(lái)查看 Redis 服務(wù)器中的緩存,如下圖所示。

? ? ? ? 可以看到,剛剛被緩存的用戶(hù)列表已經(jīng)沒(méi)有了。再次調(diào)用查詢(xún)用戶(hù)列表的接口,仍然可以看到 IDEA 的控制臺(tái)有數(shù)據(jù)庫(kù)的查詢(xún)?nèi)罩荆?Redis 服務(wù)器中又緩存了新的數(shù)據(jù)用戶(hù)列表數(shù)據(jù)。
四、總結(jié)
? ? ? ? 并不是所有的接口都適合增加緩存,但是對(duì)于類(lèi)似字典表中的數(shù)據(jù)我們完全可以進(jìn)行緩存,還有一些不經(jīng)常變化的數(shù)據(jù)也可以進(jìn)行緩存。

公眾號(hào)內(nèi)回復(fù)?【mongo】 下載 SpringBoot 整合操作 MongoDB 的文檔。
更多文章
