在Spring Boot中如何使用數(shù)據(jù)緩存
在實(shí)際開(kāi)發(fā)中,對(duì)于要反復(fù)讀寫(xiě)的數(shù)據(jù),最好的處理方式是將之在內(nèi)存中緩存一份,頻繁的數(shù)據(jù)庫(kù)訪問(wèn)會(huì)造成程序效率低下,同時(shí)內(nèi)存的讀寫(xiě)速度本身就要強(qiáng)于硬盤。Spring在這一方面給我們提供了諸多的處理手段,而Spring Boot又將這些處理方式進(jìn)一步簡(jiǎn)化,接下來(lái)我們就來(lái)看看如何在Spring Boot中解決數(shù)據(jù)緩存問(wèn)題。
創(chuàng)建Project并添加數(shù)據(jù)庫(kù)驅(qū)動(dòng)
Spring Boot的創(chuàng)建方式還是和我們前文提到的創(chuàng)建方式一樣,不同的是這里選擇添加的依賴不同,這里我們添加Web、Cache和JPA依賴,如下圖:
創(chuàng)建成功之后,接下來(lái)添加數(shù)據(jù)庫(kù)驅(qū)動(dòng),我還是使用MySQL,在pom.xml中添加數(shù)據(jù)庫(kù)驅(qū)動(dòng),如下:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.40</version> </dependency>
配置application.properties
這個(gè)application.properties的配置還是和初識(shí)在Spring Boot中使用JPA一樣,各個(gè)參數(shù)的含義我這里也不再贅述,我們直接來(lái)看代碼:
spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/sang?useUnicode=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=sang spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jackson.serialization.indent_output=true
創(chuàng)建實(shí)體類
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String name;
private String address;
private Integer age;
public Person() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Person(Long id, String name, String address, Integer age) {
this.id = id;
this.name = name;
this.address = address;
this.age = age;
}
}
創(chuàng)建實(shí)體類的Repository
public interface PersonRepository extends JpaRepository<Person,Long> {}
創(chuàng)建業(yè)務(wù)類
業(yè)務(wù)接口
public interface DemoService {
public Person save(Person person);
public void remove(Long id);
public Person findOne(Person person);
}
實(shí)現(xiàn)類
@Service
public class DemoServiceImpl implements DemoService {
@Autowired
PersonRepository personRepository;
@CachePut(value = "people", key = "#person.id")
@Override
public Person save(Person person) {
Person p = personRepository.save(person);
System.out.println("為id、key為" + p.getId() + "數(shù)據(jù)做了緩存");
return p;
}
@CacheEvict(value = "people")
@Override
public void remove(Long id) {
System.out.println("刪除了id、key為" + id + "的數(shù)據(jù)緩存");
personRepository.delete(id);
}
@Cacheable(value = "people", key = "#person.id")
@Override
public Person findOne(Person person) {
Person p = personRepository.findOne(person.getId());
System.out.println("為id、key為" + p.getId() + "數(shù)據(jù)做了緩存");
return p;
}
}@Service
public class DemoServiceImpl implements DemoService {
@Autowired
PersonRepository personRepository;
@CachePut(value = "people", key = "#person.id")
@Override
public Person save(Person person) {
Person p = personRepository.save(person);
System.out.println("為id、key為" + p.getId() + "數(shù)據(jù)做了緩存");
return p;
}
@CacheEvict(value = "people")
@Override
public void remove(Long id) {
System.out.println("刪除了id、key為" + id + "的數(shù)據(jù)緩存");
personRepository.delete(id);
}
@Cacheable(value = "people", key = "#person.id")
@Override
public Person findOne(Person person) {
Person p = personRepository.findOne(person.getId());
System.out.println("為id、key為" + p.getId() + "數(shù)據(jù)做了緩存");
return p;
}
}
關(guān)于這個(gè)實(shí)現(xiàn)類我說(shuō)如下幾點(diǎn):
1.@CachePut表示緩存新添加的數(shù)據(jù)或者更新的數(shù)據(jù)到緩存中,兩個(gè)參數(shù)value表示緩存的名稱為people,key表示緩存的key為person的id
2.@CacheEvict表示從緩存people中刪除key為id的數(shù)據(jù)
3.@Cacheable表示添加數(shù)據(jù)到緩存中,緩存名稱為people,緩存key為person的id屬性。
創(chuàng)建Controller
@RestController
public class CacheController {
@Autowired
DemoService demoService;
@RequestMapping("/put")
public Person put(Person person) {
return demoService.save(person);
}
@RequestMapping("/able")
public Person cacheable(Person person) {
return demoService.findOne(person);
}
@RequestMapping("/evit")
public String evit(Long id) {
demoService.remove(id);
return "ok";
}
}
OK ,做完這一切我們就可以來(lái)測(cè)試我們剛剛寫(xiě)的緩存了。
測(cè)試
看我們的Controller,我們有三個(gè)地址要測(cè)試,一個(gè)一個(gè)來(lái)。當(dāng)然,在 測(cè)試之前,我們先來(lái)看看初始狀態(tài)下的數(shù)據(jù)庫(kù)是什么樣子的:

首先我們?cè)跒g覽器中訪問(wèn)http://localhost:8080/able?id=1,得到如下訪問(wèn)結(jié)果:
這個(gè)時(shí)候查看控制臺(tái),輸出內(nèi)容如下:
說(shuō)是數(shù)據(jù)已經(jīng)被緩存了,這個(gè)時(shí)候我們?cè)倮^續(xù)在瀏覽器中刷新繼續(xù)請(qǐng)求id為1的數(shù)據(jù),會(huì)發(fā)現(xiàn)控制臺(tái)不會(huì)繼續(xù)打印日志出來(lái),就是因?yàn)閿?shù)據(jù)已被存于緩存之中了。
接下來(lái)我們向?yàn)g覽器中輸入http://localhost:8080/put?age=47&name=奧巴牛&address=米國(guó),訪問(wèn)結(jié)果如下:
這個(gè)時(shí)候查看控制臺(tái)打印的日志如下:
再查看數(shù)據(jù)表,數(shù)據(jù)已插入成功:
此時(shí),我們?cè)跒g覽器中輸入http://localhost:8080/able?id=106,訪問(wèn)剛剛插入的這條數(shù)據(jù),結(jié)果如下:
這個(gè)時(shí)候查看控制臺(tái),發(fā)現(xiàn)并沒(méi)有數(shù)據(jù)數(shù)據(jù),就是因?yàn)閿?shù)據(jù)已經(jīng)處于緩存中了。
最后我們?cè)跒g覽器中輸入http://localhost:8080/evit?id=106,將數(shù)據(jù)從緩存中移除,訪問(wèn)結(jié)果如下:
這個(gè)時(shí)候查看控制臺(tái),已經(jīng)提示緩存移除掉了:
同時(shí)數(shù)據(jù)也從數(shù)據(jù)庫(kù)刪除掉了,這個(gè)時(shí)候如果還需要該數(shù)據(jù)則需要我們繼續(xù)向表中添加數(shù)據(jù)。
緩存技術(shù)切換
Spring Boot默認(rèn)情況下使用ConcurrentMapCacheManager作為緩存技術(shù),有的時(shí)候你可能想替換為其他的緩存方式,在Spring Boot中進(jìn)行緩存的切換非常簡(jiǎn)單,我這里以Google提供的Guava為例,如果要使用這種緩存策略,只需要添加相應(yīng)的依賴即可,如下:
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>20.0</version> </dependency>
就這樣就可以了。實(shí)際上在Spring Boot中,底層使用哪一種緩存我們并不必做過(guò)多考慮,切換的方式也很簡(jiǎn)單,如上文引入相應(yīng)的依賴即可,我們只需要把上層的邏輯寫(xiě)好即可。
本文案例下載:
本文GitHub地址https://github.com/lenve/JavaEETest/tree/master/Test25-Cache.
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Spring Boot Web 靜態(tài)文件緩存處理的方法
- spring boot+spring cache實(shí)現(xiàn)兩級(jí)緩存(redis+caffeine)
- Spring Boot 中使用cache緩存的方法
- SpringBoot項(xiàng)目中使用redis緩存的方法步驟
- 實(shí)例詳解Spring Boot實(shí)戰(zhàn)之Redis緩存登錄驗(yàn)證碼
- Spring Boot緩存實(shí)戰(zhàn) EhCache示例
- Spring Boot 基于注解的 Redis 緩存使用詳解
- 詳解Spring Boot使用redis實(shí)現(xiàn)數(shù)據(jù)緩存
- Spring Boot集成Redis實(shí)現(xiàn)緩存機(jī)制(從零開(kāi)始學(xué)Spring Boot)
- 在Spring Boot中實(shí)現(xiàn)HTTP緩存的方法
相關(guān)文章
Java 客戶端操作 FastDFS 實(shí)現(xiàn)文件上傳下載替換刪除功能
這篇文章主要介紹了Java 客戶端操作 FastDFS 實(shí)現(xiàn)文件上傳下載替換刪除功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
Java并發(fā)編程之關(guān)鍵字volatile知識(shí)總結(jié)
今天帶大家學(xué)習(xí)java的相關(guān)知識(shí),文章圍繞著Java關(guān)鍵字volatile展開(kāi),文中有非常詳細(xì)的知識(shí)總結(jié),需要的朋友可以參考下2021-06-06
k8s部署springboot實(shí)現(xiàn)前后端分離項(xiàng)目
本文主要介紹了k8s部署springboot實(shí)現(xiàn)前后端分離項(xiàng)目,主要包括配置文件、鏡像構(gòu)建和容器編排等方面,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
Java過(guò)濾器filter_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java過(guò)濾器filter,通過(guò)過(guò)濾器,可以對(duì)來(lái)自客戶端的請(qǐng)求進(jìn)行攔截,進(jìn)行預(yù)處理或者對(duì)最終響應(yīng)給客戶端的數(shù)據(jù)進(jìn)行處理后再輸出2017-07-07
如何解決springboot自動(dòng)重啟問(wèn)題
這篇文章主要介紹了如何解決springboot自動(dòng)重啟問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09

