在實際開發中,對于要反復讀寫的數據,最好的處理方式是將之在內存中緩存一份,頻繁的數據庫訪問會造成程序效率低下,同時內存的讀寫速度本身就要強于硬盤。spring在這一方面給我們提供了諸多的處理手段,而spring boot又將這些處理方式進一步簡化,接下來我們就來看看如何在spring boot中解決數據緩存問題。
創建project并添加數據庫驅動
spring boot的創建方式還是和我們前文提到的創建方式一樣,不同的是這里選擇添加的依賴不同,這里我們添加web、cache和jpa依賴,如下圖:
創建成功之后,接下來添加數據庫驅動,我還是使用mysql,在pom.xml中添加數據庫驅動,如下:
1
2
3
4
5
|
<dependency> <groupid>mysql</groupid> <artifactid>mysql-connector-java</artifactid> <version> 5.1 . 40 </version> </dependency> |
配置application.properties
這個application.properties的配置還是和初識在spring boot中使用jpa一樣,各個參數的含義我這里也不再贅述,我們直接來看代碼:
1
2
3
4
5
6
7
8
|
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 |
創建實體類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
@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; } } |
創建實體類的repository
1
|
public interface personrepository extends jparepository<person, long > {} |
創建業務類
業務接口
1
2
3
4
5
6
7
|
public interface demoservice { public person save(person person); public void remove( long id); public person findone(person person); } |
實現類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
@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() + "數據做了緩存" ); return p; } @cacheevict (value = "people" ) @override public void remove( long id) { system.out.println( "刪除了id、key為" + id + "的數據緩存" ); 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() + "數據做了緩存" ); 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() + "數據做了緩存" ); return p; } @cacheevict (value = "people" ) @override public void remove( long id) { system.out.println( "刪除了id、key為" + id + "的數據緩存" ); 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() + "數據做了緩存" ); return p; } } |
關于這個實現類我說如下幾點:
1.@cacheput表示緩存新添加的數據或者更新的數據到緩存中,兩個參數value表示緩存的名稱為people,key表示緩存的key為person的id
2.@cacheevict表示從緩存people中刪除key為id的數據
3.@cacheable表示添加數據到緩存中,緩存名稱為people,緩存key為person的id屬性。
創建controller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@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 ,做完這一切我們就可以來測試我們剛剛寫的緩存了。
測試
看我們的controller,我們有三個地址要測試,一個一個來。當然,在 測試之前,我們先來看看初始狀態下的數據庫是什么樣子的:
首先我們在瀏覽器中訪問,得到如下訪問結果:
這個時候查看控制臺,輸出內容如下:
說是數據已經被緩存了,這個時候我們再繼續在瀏覽器中刷新繼續請求id為1的數據,會發現控制臺不會繼續打印日志出來,就是因為數據已被存于緩存之中了。
接下來我們向瀏覽器中輸入http://localhost:8080/put?age=47&name=奧巴牛&address=米國,訪問結果如下:
這個時候查看控制臺打印的日志如下:
再查看數據表,數據已插入成功:
此時,我們在瀏覽器中輸入http://localhost:8080/able?id=106,訪問剛剛插入的這條數據,結果如下:
這個時候查看控制臺,發現并沒有數據數據,就是因為數據已經處于緩存中了。
最后我們在瀏覽器中輸入http://localhost:8080/evit?id=106,將數據從緩存中移除,訪問結果如下:
這個時候查看控制臺,已經提示緩存移除掉了:
同時數據也從數據庫刪除掉了,這個時候如果還需要該數據則需要我們繼續向表中添加數據。
緩存技術切換
spring boot默認情況下使用concurrentmapcachemanager作為緩存技術,有的時候你可能想替換為其他的緩存方式,在spring boot中進行緩存的切換非常簡單,我這里以google提供的guava為例,如果要使用這種緩存策略,只需要添加相應的依賴即可,如下:
1
2
3
4
5
|
<dependency> <groupid>com.google.guava</groupid> <artifactid>guava</artifactid> <version> 20.0 </version> </dependency> |
就這樣就可以了。實際上在spring boot中,底層使用哪一種緩存我們并不必做過多考慮,切換的方式也很簡單,如上文引入相應的依賴即可,我們只需要把上層的邏輯寫好即可。
本文案例下載:
本文github地址https://github.com/lenve/javaeetest/tree/master/test25-cache.
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blog.csdn.net/u012702547/article/details/54142243