(六)SpringBoot2.0基礎篇- MyBatis、Redis整合(JedisCluster叢集連線)
一、環境
Redis:4.0.9
SpringBoot:2.0.1
二、SpringBoot整合Redis
1、專案基本搭建:
2、新增maven相關依賴和Redis的連線資訊:
Pom.xml
<!-- Redis的依賴庫 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> <version>1.4.7.RELEASE</version> </dependency> <!-- fastJson 依賴庫 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.28</version> </dependency> <!-- aop依賴庫--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
application.properties:
spring.redis.cluster.nodes=192.168.1.124:7001
3、建立RedisProperties屬性類和RedisConfig配置類,將JedisCluster放入Spring容器中:
RedisConfigurationProperties:
package com.cn.common.redis; import java.util.ArrayList; import java.util.List; import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Configuration; /** * @program: spring-boot-example * @description: * @author: * @create: 2018-05-16 15:15 **/ @Configuration @ConfigurationProperties(prefix = "spring.redis.cluster") public class RedisConfigurationProperties { private List<String> nodes = newArrayList<>(); public List<String> getNodes() { return nodes; } public void setNodes(List<String> nodes) { this.nodes = nodes; } }
RedisConfig:
package com.cn.common.redis; import java.util.HashSet; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import redis.clients.jedis.HostAndPort; import redis.clients.jedis.JedisCluster; /** * @program: spring-boot-example * @description: Redis的配置檔案 * @author: * @create: 2018-05-16 15:01 **/ @Configuration public class RedisConfig { @Autowired private RedisConfigurationProperties redisConfigurationProperties; @Bean public JedisCluster jedisCluster() { Set<HostAndPort> nodeSet = new HashSet<>(); for(String node :redisConfigurationProperties.getNodes()) { String[] split = node.split(":"); nodeSet.add(new HostAndPort(split[0],Integer.valueOf(split[1]))); } return new JedisCluster(nodeSet); } }
4、建立封裝Redis的增刪改查(JedisService,JedisServiceImpl):
package com.cn.common.service; import java.util.List; import java.util.Map; import redis.clients.jedis.GeoRadiusResponse; /** * @program: spring-boot-example * @description: * @author: * @create: 2018-05-16 15:27 **/ public interface JedisService { /** * @Description: 是否存在 * @Param: * @return: * @Author: * @Date: 2018/5/16 */ boolean exists(String key); /** * @Description:快取set值 * @Param: seconds:快取時間,不設定則為0 * @return: * @Author: * @Date: 2018/5/16 */ String set(String key,String value,int seconds); /** * @Description: 重新快取getSet值 * @Param: * @return: * @Author: * @Date: 2018/5/16 */ String getSet(String key,String value, int seconds); /** * @Description: 獲取set值 * @Param: * @return: * @Author: * @Date: 2018/5/16 */ String get(String key); /** * @Description: 新增地理位置 * @Param: * @return: * @Author: * @Date: 2018/5/16 */ Long geoadd(String key,double longitude,double latitude,byte[] obj); /** * @Description: 地理位置查詢 * @Param: * @return: * @Author: * @Date: 2018/5/16 */ List<GeoRadiusResponse> georadius(String key,double longitude,double latitude); /** * @Description: 刪除key * @Param: * @return: * @Author: * @Date: 2018/5/16 */ void delKey(String key); /** * @Description: 刪除native key * @Param: * @return: * @Author: * @Date: 2018/5/16 */ void delNativeKey(String key); /** * @Description: 獲取map格式的資料 * @Param: * @return: * @Author: * @Date: 2018/5/16 */ Map<String ,Object> getMapData(String key); /** * @Description: 加鎖,避免重複提交 * @Param: * @return: * @Author: * @Date: 2018/5/16 */ boolean lock(String key,int seconds); /** * @Description: 解鎖 * @Param: * @return: * @Author: * @Date: 2018/5/16 */ void unlock(String key); /** * @Description: 統計鎖定次數 * @Param: * @return: * @Author: * @Date: 2018/5/16 */ String getLocakValue(String key); }JedisService.java
package com.cn.common.service; import com.alibaba.fastjson.JSON; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import redis.clients.jedis.GeoRadiusResponse; import redis.clients.jedis.JedisCluster; /** * @program: spring-boot-example * @description: * @author: * @create: 2018-05-16 15:45 **/ @Service public class JedisServiceImpl implements JedisService { @Autowired private JedisCluster jedisCluster; @Override public boolean exists(String key) { boolean flag = false; flag = jedisCluster.exists(key); return flag; } @Override public String set(String key, String value, int seconds) { String responseResult = jedisCluster.set(key,value); if(seconds!=0) jedisCluster.expire(key,seconds); return responseResult; } @Override public String getSet(String key, String value, int seconds) { String jedisClusterSet = jedisCluster.getSet(key, value); jedisCluster.expire(key,seconds); return jedisClusterSet; } @Override public String get(String key) { String str = jedisCluster.get(key); return str; } @Override public Long geoadd(String key, double longitude, double latitude, byte[] obj) { return null; } @Override public List<GeoRadiusResponse> georadius(String key, double longitude, double latitude) { return null; } @Override public void delKey(String key) { jedisCluster.del(key); } @Override public void delNativeKey(String key) { jedisCluster.del(key); } @Override public Map<String, Object> getMapData(String key) { String str = jedisCluster.get(key); Map<String,Object> map = JSON.parseObject(str, Map.class); return map; } /** * @Description: 如為第一次,則加上鎖,每次呼叫值會自動加1 * @Param: * @return: * @Author: * @Date: 2018/5/16 */ @Override public boolean lock(String key, int seconds) { if(jedisCluster.incr(key)==1) { jedisCluster.expire(key,seconds); return false; } return true; } @Override public void unlock(String key) { jedisCluster.del(key); } @Override public String getLocakValue(String key) { return jedisCluster.get(key); } }JedisServiceImpl.java
5、建立註解類和切面類(我使用註解來實現快取的set和get):
RedisCache:
package com.cn.common.redis; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Description: 加上該註解,代理service命中快取則從快取中讀取資料,否則從service業務邏輯獲得,並存入快取 * @Param: * @return: * @Author: * @Date: 2018/5/16 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD,ElementType.TYPE}) @Documented public @interface RedisCache { /** * @Description: 資料返回型別 * @Param: * @return: * @Author: * @Date: 2018/5/16 */ Class type(); /** * @Description: 資料快取時間單位s秒 * @Param: 預設10分鐘 * @return: * @Author: * @Date: 2018/5/16 */ int cacheTime() default 600; }
RedisCacheAspect:
package com.cn.common.redis; import com.alibaba.fastjson.JSON; import com.cn.common.service.JedisService; import java.lang.reflect.Method; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * @program: spring-boot-example * @description: * @author: * @create: 2018-05-16 16:29 **/ @Aspect @Component public class RedisCacheAspect { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private JedisService jedisService; @Pointcut("execution(public * com.cn.service..*.*(..))") public void webAspect(){} @Around("webAspect()") public Object redisCache(ProceedingJoinPoint pjp) throws Throwable { //得到類名、方法名和引數 String redisResult = ""; String className = pjp.getTarget().getClass().getName(); String methodName = pjp.getSignature().getName(); Object[] args = pjp.getArgs(); //根據類名,方法名和引數生成key String key = genKey(className,methodName,args); logger.info("生成的key[{}]",key); //得到被代理的方法 Signature signature = pjp.getSignature(); if(!(signature instanceof MethodSignature)){ throw new IllegalArgumentException(); } MethodSignature methodSignature = (MethodSignature) signature; Method method = pjp.getTarget().getClass().getMethod(methodSignature.getName(),methodSignature.getParameterTypes()); //得到被代理的方法上的註解 Class modelType = method.getAnnotation(RedisCache.class).type(); int cacheTime = method.getAnnotation(RedisCache.class).cacheTime(); Object result = null; if(!jedisService.exists(key)) { logger.info("快取未命中"); //快取不存在,則呼叫原方法,並將結果放入快取中 result = pjp.proceed(args); redisResult = JSON.toJSONString(result); jedisService.set(key,redisResult,cacheTime); } else{ //快取命中 logger.info("快取命中"); redisResult = jedisService.get(key); //得到被代理方法的返回值型別 Class returnType = method.getReturnType(); result = JSON.parseObject(redisResult,returnType); } return result; } /** * @Description: 生成key * @Param: * @return: * @Author: * @Date: 2018/5/16 */ private String genKey(String className, String methodName, Object[] args) { StringBuilder sb = new StringBuilder("SpringBoot:"); sb.append(className); sb.append("_"); sb.append(methodName); sb.append("_"); for (Object object: args) { logger.info("obj:"+object); if(object!=null) { sb.append(object+""); sb.append("_"); } } return sb.toString(); } }
6、在StudentServiceImpl中加入快取註釋:
StudentServiceImpl:
package com.cn.service; import com.cn.common.redis.RedisCache; import com.cn.entity.Student; import com.cn.mapper.StudentMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @program: spring-boot-example * @description: * @author: * @create: 2018-05-11 10:55 **/ @Service public class StudentServiceImpl implements StudentService{ @Autowired private StudentMapper studentMapper; @Override @RedisCache(type = Student.class) public Student getStudentByPrimaryKey(int id) { return studentMapper.selectByPrimaryKey(id); } }
7、啟動測試:
第一次呼叫:
檢視控制檯:
第二次呼叫:
檢視控制檯:
發現第二次未打印出MyBatis的查詢日誌,並且顯示快取命中,通過RedisDeskManager工具檢視Redis快取:
相關推薦
(六)SpringBoot2.0基礎篇- MyBatis、Redis整合(JedisCluster叢集連線)
一、環境 Redis:4.0.9 SpringBoot:2.0.1 二、SpringBoot整合Redis 1、專案基本搭建: 2、新增maven相關依賴和Redis的連線資訊: Pom.xml <!-- Redis的依賴庫 -->
(五)SpringBoot2.0基礎篇- Mybatis與外掛生成程式碼
SpringBoot與Mybatis合併 一、建立SpringBoot專案,引入相關依賴包: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"
Git學習0基礎篇(下)
擴展 創建 不同 sheet id_rsa con 簡單 托管 讀取數據 server上的 Git - 協議 Git能夠使用四種基本的協議傳輸資料:本地協議(Loc
Docker 入門 只要這篇就夠了 (純乾貨適合0基礎小白)
與sgy一起開啟
python3-開發面試題(python)6.23基礎篇(2)
漢字 2個 特殊 問題 ase 第一個 else () 判斷 1、請至少列舉5個 PEP8 規範(越多越好)。 一、代碼編排 1、縮進。4個空格的縮進,不使用Tap,更不能混合使用Tap和空格 2、每行最大長度79,換行可以使用反斜杠,最好使用圓括號。換行點要在操作符
機器學習讀書筆記(三)決策樹基礎篇之從相親說起
方法 事務 家裏 分類 筆記 判斷 都是 rom tro 一、決策樹 決策樹是什麽?決策樹(decision tree)是一種基本的分類與回歸方法。舉個通俗易懂的例子,如下圖所示的流程圖就是一個決策樹,長方形代表判斷模塊(decision block),橢圓形成代
C語言基礎篇-數據類型(二)關鍵字
至少 硬件 邏輯結構 內存空間 結構 根據 什麽 操作 自定義 導航: 1. 數據類型 2. 自定義類型 3. 邏輯結構 4. 類型修飾符 5. 雜項 ----->x<------------->x<--------------
C++基礎篇--成員函式同名隱藏(overwrite)
不同於過載和覆蓋的正面功能,同名隱藏在程式設計中應儘量避免:1)由於缺少類似virtual這種明顯的語法特徵,很多人容易忽略C++“隱藏”機制的存在,當派生類與基類函式同名時就和過載、覆蓋等機制混淆,既降低可讀性,又易產生bug。2)從面向物件思想的角度,隱藏也應儘量避免。基類裡使用普通函式就代表這
EA&UML日拱一卒-0基礎學習微信小程式(4)- 安裝開發工具
小程式賬號申請成功之後的工作就是準備開發環境。 微信小程式管理的頁面如下:左面是分類標籤,根據分類的不同,會在右面顯示相應的內容,目前的狀態是【首頁】被選擇的狀態。 在上述頁面中選擇紅框中的【下載開發工具】,就可以開啟下面的下載地址頁面。 根據作業系統選擇合適
EA&UML日拱一卒-0基礎學習微信小程式(1)- 開篇
這次選了一個時髦的話題,同時也是一個真正從0開始的話題----微信小程式。說它時髦當然是因為這東西出來沒多長時間,許多開發者不要說做過,恐怕連用都沒有用過。說從0開始是因為作者本人不光是對微信小程式沒有概念,恐怕對開發中用到的技術,手法同樣沒有經驗。 選題的目的 第一當
mysql基礎篇之多表查詢(一)
1、前面的 select * from emp limit 5; 2、Null的用法 0和null是不一樣的,null表示空值,沒有值,0表示一個確定的值 其中null不能參與如下運算:<&g
EA&UML日拱一卒-0基礎學習微信小程式(5)- Hello world!
全貌 上一篇文章的最後,我們的開發工具是下面的狀態。 畫面的最左邊是導航選單,用於切換編輯,除錯,專案設定等功能。今天我們集中說明編輯功能。 導航選單的右側分為3個大的區域,分別是小程式執行區域,目錄樹和程式碼編輯區域。 小程式執行區域 該區域的最上面有兩個
EA&UML日拱一卒-0基礎學習微信小程式(6)- 配置檔案的形式和內容
上篇文章中講到,小程式有兩種配置檔案,本別針對的是小程式全體和單獨的頁面,本文從形式和內容兩個方面來解析小程式中的配置檔案。 形式 從配置檔案的副檔名json可以知道配置檔案的格式是JSON(Ja
5、(五)外匯學習基礎篇之銀行間外匯掉期交易
3、2015-04-20,機構A和機構B通過外匯交易系統C-Swap功能成交一筆1Y美元兌人民幣掉期交易,成交量為10手,系統自動匹配機構A Offer報價和機構B Bid 報價49.00bp(B先下單)。當時外匯交易系統即期最優賣價為6.1600,則機構A在近端買入USD10,000,000,遠端賣出US
SpringBoot2.0 自定義Json序列化規則(忽略value為null的key序列化)
最近公司專案重構,發現介面返回的json資料中存在有value值為null 的key,這些應該被視為廢資料,不應該輸出給前端佔用頻寬,於是去修改json序列化的方式,在spring中我們都知道去xml配置檔案中加一行配置或者在輸出模型上加一@JsonInclud
springboot2.0---控制檯列印Mybatis的SQL記錄
題記:每次使用mybatis出錯,都不知道sql原因,debug也不出結果,索性將其打印出來,更加容易排錯。 親測有效,只需要將下面的logback.xml放置在resource目錄下即可列印。 <?xml version="1.0" encoding="UTF-8"?> <c
Spring boot開發步驟 (包含jsp、mybatis、FastJSON整合)
專案建立好後 先匯入jar 包 /* 注意 這個不能放在dependencies內部 必須放在dependencies外部 */ <parent> <groupId>org.springframework.boot</groupId&g
python+appium-desktop:安卓(android)7.0以上使用appium無法定位元素(無法refresh)且 無法執行指令碼
--解決方法: 啟動appium時配置中新增: "automationName":"uiautomator2" --擴充套件: 想支援安卓7.0及以上版本需要滿足一下3點: 1、使用appium-desktop 1.6.3以及以上版本 2、啟動appium的driver配置新增:"
篇一、元件通訊(父級傳值給子元件 props )
props 用法(props寫在子元件中) 父元件 子元件 ****--- 番外篇 ---**** 1、傳遞靜態 Prop 例:<blog-post title="My journe