SpringBoot整合Redis使用@Cacheable和RedisTemplate
對(duì)之前網(wǎng)站做了一些很簡單的優(yōu)化,給用戶列表加了一個(gè)分頁功能。
分頁就更好考慮加載速度,如果換一頁就要等幾秒,那體驗(yàn)感是非常差的。
因此想到了加一個(gè)redis緩存。
springboot整合redis有兩種方式:
- 一、使用注解,@EnableCaching @Cacheable . . . 等
- 二、使用RedisTemplate
兩者都能操作緩存,使用RedisTemplate 操作肯定是比使用注解靈活、方便。但是從理論上來講注解方式速度應(yīng)該更快,因?yàn)槭褂米⒔馊绻诰彺嬷杏芯椭苯訌木彺嬷腥?,不用進(jìn)入方法。而RedisTemplate 必須進(jìn)入方法,而且執(zhí)行寫的邏輯判斷。
下面記錄一下我給分頁做緩存的思路,肯定有很多不好的地方,希望大家可以給我指出。
業(yè)務(wù)場景是后臺(tái)管理系統(tǒng),不用過于注重實(shí)時(shí)數(shù)據(jù)刷新,就設(shè)置一個(gè)小時(shí)過期。
我的思路是:
第一次加載頁面,就從數(shù)據(jù)庫把前面四頁的數(shù)據(jù)從數(shù)據(jù)庫查詢出來,這樣第一次稍微多等一下,后面換頁幾乎不用等待,這樣體驗(yàn)比較好。然后每次換頁都換查看有沒有在緩存中,沒用就加入緩存。
@RequestMapping("/appUser/{currentPage}") public R<String> getTableData1(@PathVariable int currentPage) { //第一次請(qǐng)求 前面幾頁用到的概率更大 把后面三頁存入redis 減少后面分頁請(qǐng)求的時(shí)間 以后每次加載頁面都把那頁放入redis // 設(shè)置一個(gè)小時(shí)過期 Page<AppUser> appUserPage = new Page<AppUser>(currentPage, 12); if (currentPage == 1 && !redisTemplate.hasKey(1)) { for (int i = 1; i < 5; i++) { Page<AppUser> redisPage = new Page<AppUser>(i, 12); redisTemplate.opsForValue().set(i, appUserServiceInterface.page(redisPage), 1, TimeUnit.HOURS); } } else if (!redisTemplate.hasKey(currentPage)) { redisTemplate.opsForValue().set(currentPage, appUserServiceInterface.page(appUserPage), 1, TimeUnit.HOURS); return R.success((Page<AppUser>) redisTemplate.opsForValue().get(currentPage)); } else if (redisTemplate.hasKey(currentPage)) { return R.success((Page<AppUser>) redisTemplate.opsForValue().get(currentPage)); } return R.success(appUserServiceInterface.page(appUserPage)); }
數(shù)據(jù)統(tǒng)計(jì)那塊我又試了試注解。
先要在啟動(dòng)加上 @EnableCaching注解
注解使用就簡單,在方法上加上@Cacheable 就行,執(zhí)行方法前會(huì)查詢r(jià)edis緩存是否有對(duì)應(yīng)的key,有就直接取值,沒有就執(zhí)行方法。
value = "appUserData" 是緩存區(qū)的名字 , key是鍵的名字 。
以下的鍵值就是 appUserData : : userArea
@RequestMapping ("/userArea") @Cacheable(value = "appUserData",key ="'userArea'") public R<String> area() { ? ? List<AppUser> userList = appUserServiceInterface.list(); ? ? List<String> areaList = new ArrayList<>(); ? ? for (AppUser appUser : userList) { ? ? ? ? areaList.add(appUser.getArea()); ? ? } ? ? //放入map記錄每個(gè)月份出現(xiàn)的次數(shù) ? ? Map<String, Integer> areaTimes = new HashMap<>(); ? ? for (String s : areaList) { ? ? ? ? if (!areaTimes.containsKey(s)) { ? ? ? ? ? ? areaTimes.put(s, 1); ? ? ? ? }else { ? ? ? ? ? ? areaTimes.put(s, areaTimes.get(s) + 1); ? ? ? ? } ? ? } ? ? //排序 ? ? //自定義比較器 ? ? Comparator<Map.Entry<String, Integer>> valCmp = new Comparator<Map.Entry<String, Integer>>() { ? ? ? ? @Override ? ? ? ? public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { ? ? ? ? ? ? // TODO Auto-generated method stub ? ? ? ? ? ? return o2.getValue() - o1.getValue(); ?// 降序排序,如果想升序就反過來 ? ? ? ? } ? ? }; ? ? //將map轉(zhuǎn)成List,map的一組key,value對(duì)應(yīng)list一個(gè)存儲(chǔ)空間 ? ? List<Map.Entry<String, Integer>> mapList = new ArrayList<Map.Entry<String, Integer>>(areaTimes.entrySet()); //傳入maps實(shí)體 ? ? Collections.sort(mapList, valCmp); ? ? //取前8 ? ? int len = mapList.size(); ? ? for (int i = 0; i < len-8; i++) { ? ? ? ? mapList.remove(8); ? ? } ? ? Map<String, String> resMap = new HashMap<>(); ? ? for (Map.Entry<String, Integer> m : mapList) { ? ? ? ? resMap.put(m.getKey(), m.getValue().toString()); ? ? } ? ? return R.success(resMap); }
其他注解:
- @CachePut
- @Caching
- @CacheEvict
到此這篇關(guān)于SpringBoot整合Redis使用@Cacheable和RedisTemplate的文章就介紹到這了,更多相關(guān)SpringBoot整合Redis內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis CachingExecutor二級(jí)緩存使用示例詳解
這篇文章主要介紹了?Mybatis的CachingExecutor與二級(jí)緩存使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09Spring boot整合mybatis實(shí)現(xiàn)過程圖解
這篇文章主要介紹了Spring boot整合mybatis實(shí)現(xiàn)過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08Java 用反射設(shè)置對(duì)象的屬性值實(shí)例詳解
這篇文章主要介紹了Java 用反射設(shè)置對(duì)象的屬性值實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05詳解Spring Boot 目錄文件結(jié)構(gòu)
這篇文章主要介紹了Spring Boot 目錄文件結(jié)構(gòu)的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07