SpringBoot實(shí)戰(zhàn):整合Redis、mybatis,封裝RedisUtils工具類(lèi)等(附源碼)
作者:陳彥斌
cnblogs.com/chenyanbin/p/13515268.html
創(chuàng)建SpringBoot項(xiàng)目
在線創(chuàng)建方式
網(wǎng)址:https://start.spring.io/

然后創(chuàng)建Controller、Mapper、Service包

SpringBoot整合Redis
引入Redis依賴(lài)
<dependency>
????<groupId>org.springframework.bootgroupId>
????<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
完整pom.xml
<project?xmlns="http://maven.apache.org/POM/4.0.0"?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
????xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?https://maven.apache.org/xsd/maven-4.0.0.xsd">
????<modelVersion>4.0.0modelVersion>
????<parent>
????????<groupId>org.springframework.bootgroupId>
????????<artifactId>spring-boot-starter-parentartifactId>
????????<version>2.3.3.RELEASEversion>
????????<relativePath/>?
????parent>
????<groupId>com.cybgroupId>
????<artifactId>chenyb-mobile-redisartifactId>
????<version>0.0.1-SNAPSHOTversion>
????<name>chenyb-mobile-redisname>
????<description>Demo?project?for?Spring?Bootdescription>
????<properties>
????????<java.version>1.8java.version>
????properties>
????<dependencies>
????????<dependency>
????????????<groupId>org.springframework.bootgroupId>
????????????<artifactId>spring-boot-starter-webartifactId>
????????dependency>
????????<dependency>
????????????<groupId>org.springframework.bootgroupId>
????????????<artifactId>spring-boot-starter-testartifactId>
????????????<scope>testscope>
????????????<exclusions>
????????????????<exclusion>
????????????????????<groupId>org.junit.vintagegroupId>
????????????????????<artifactId>junit-vintage-engineartifactId>
????????????????exclusion>
????????????exclusions>
????????dependency>
????????<dependency>
????????????<groupId>io.projectreactorgroupId>
????????????<artifactId>reactor-testartifactId>
????????????<scope>testscope>
????????dependency>
????????
????????<dependency>
????????????<groupId>org.springframework.bootgroupId>
????????????<artifactId>spring-boot-starter-data-redisartifactId>
????????dependency>
????dependencies>
????<build>
????????<plugins>
????????????<plugin>
????????????????<groupId>org.springframework.bootgroupId>
????????????????<artifactId>spring-boot-maven-pluginartifactId>
????????????plugin>
????????plugins>
????build>
project>
設(shè)置Redis的Template

RedisConfig.java
package?com.cyb.mobile.config;
import?org.springframework.context.annotation.Bean;
import?org.springframework.context.annotation.Configuration;
import?org.springframework.data.redis.connection.RedisConnectionFactory;
import?org.springframework.data.redis.core.RedisTemplate;
import?org.springframework.data.redis.serializer.RedisSerializer;
import?org.springframework.data.redis.serializer.StringRedisSerializer;
/**
?*?@ClassName:RedisConfig
?*?@Description:Redis配置類(lèi)
?*?@Author:chenyb
?*?@Date:2020/8/16 11:48 下午
?*?@Versiion:1.0
?*/
@Configuration?//當(dāng)前類(lèi)為配置類(lèi)
public?class?RedisConfig?{
????@Bean?//redisTemplate注入到Spring容器
????public?RedisTemplate?redisTemplate(RedisConnectionFactory?factory) {
????????RedisTemplate?redisTemplate=new?RedisTemplate<>();
????????RedisSerializer?redisSerializer?=?new?StringRedisSerializer();
????????redisTemplate.setConnectionFactory(factory);
????????//key序列化
????????redisTemplate.setKeySerializer(redisSerializer);
????????//value序列化
????????redisTemplate.setValueSerializer(redisSerializer);
????????//value?hashmap序列化
????????redisTemplate.setHashKeySerializer(redisSerializer);
????????//key?hashmap序列化
????????redisTemplate.setHashValueSerializer(redisSerializer);
????????return?redisTemplate;
????}
}
設(shè)置Redis連接信息

#?連接的那個(gè)數(shù)據(jù)庫(kù)
spring.redis.database=0
#?redis服務(wù)的ip地址
spring.redis.host=192.168.199.142
#?redis端口號(hào)
spring.redis.port=6379
#?redis的密碼,沒(méi)設(shè)置過(guò)密碼,可為空
spring.redis.password=12345678
Redis工具類(lèi)
redisTemplate API
opsForValue ==》String
opsForSet ==》Set
opsForHash ==》hash
opsForZset ==》SortSet
opsForList ==》list隊(duì)列
RedisUtils.java

package?com.cyb.mobile.utils;
import?org.springframework.beans.factory.annotation.Autowired;
import?org.springframework.data.redis.core.*;
import?org.springframework.stereotype.Service;
import?java.io.Serializable;
import?java.util.List;
import?java.util.Set;
import?java.util.concurrent.TimeUnit;
/**
?*?@ClassName:RedisUtils
?*?@Description:Redis工具類(lèi)
?*?@Author:chenyb
?*?@Date:2020/8/17 12:05 上午
?*?@Versiion:1.0
?*/
@Service
public?class?RedisUtils?{
????@Autowired
????private?RedisTemplate?redisTemplate;
????private?static?double?size?=?Math.pow(2,?32);
????/**
?????*?寫(xiě)入緩存
?????*
?????*?@param?key
?????*?@param?offset???位?8Bit=1Byte
?????*?@return
?????*/
????public?boolean?setBit(String?key,?long?offset,?boolean?isShow)?{
????????boolean?result?=?false;
????????try?{
????????????ValueOperations?operations?=?redisTemplate.opsForValue();
????????????operations.setBit(key,?offset,?isShow);
????????????result?=?true;
????????}?catch?(Exception?e)?{
????????????e.printStackTrace();
????????}
????????return?result;
????}
????/**
?????*?寫(xiě)入緩存
?????*
?????*?@param?key
?????*?@param?offset
?????*?@return
?????*/
????public?boolean?getBit(String?key,?long?offset)?{
????????boolean?result?=?false;
????????try?{
????????????ValueOperations?operations?=?redisTemplate.opsForValue();
????????????result?=?operations.getBit(key,?offset);
????????}?catch?(Exception?e)?{
????????????e.printStackTrace();
????????}
????????return?result;
????}
????/**
?????*?寫(xiě)入緩存
?????*
?????*?@param?key
?????*?@param?value
?????*?@return
?????*/
????public?boolean?set(final?String?key,?Object?value)?{
????????boolean?result?=?false;
????????try?{
????????????ValueOperations?operations?=?redisTemplate.opsForValue();
????????????operations.set(key,?value);
????????????result?=?true;
????????}?catch?(Exception?e)?{
????????????e.printStackTrace();
????????}
????????return?result;
????}
????/**
?????*?寫(xiě)入緩存設(shè)置時(shí)效時(shí)間
?????*
?????*?@param?key
?????*?@param?value
?????*?@return
?????*/
????public?boolean?set(final?String?key,?Object?value,?Long?expireTime)?{
????????boolean?result?=?false;
????????try?{
????????????ValueOperations?operations?=?redisTemplate.opsForValue();
????????????operations.set(key,?value);
????????????redisTemplate.expire(key,?expireTime,?TimeUnit.SECONDS);
????????????result?=?true;
????????}?catch?(Exception?e)?{
????????????e.printStackTrace();
????????}
????????return?result;
????}
????/**
?????*?批量刪除對(duì)應(yīng)的value
?????*
?????*?@param?keys
?????*/
????public?void?remove(final?String...?keys)?{
????????for?(String?key?:?keys)?{
????????????remove(key);
????????}
????}
????/**
?????*?刪除對(duì)應(yīng)的value
?????*
?????*?@param?key
?????*/
????public?void?remove(final?String?key)?{
????????if?(exists(key))?{
????????????redisTemplate.delete(key);
????????}
????}
????/**
?????*?判斷緩存中是否有對(duì)應(yīng)的value
?????*
?????*?@param?key
?????*?@return
?????*/
????public?boolean?exists(final?String?key)?{
????????return?redisTemplate.hasKey(key);
????}
????/**
?????*?讀取緩存
?????*
?????*?@param?key
?????*?@return
?????*/
????public?Object?get(final?String?key)?{
????????Object?result?=?null;
????????ValueOperations?operations?=?redisTemplate.opsForValue();
????????result?=?operations.get(key);
????????return?result;
????}
????/**
?????*?哈希?添加
?????*
?????*?@param?key
?????*?@param?hashKey
?????*?@param?value
?????*/
????public?void?hmSet(String?key,?Object?hashKey,?Object?value)?{
????????HashOperations?hash?=?redisTemplate.opsForHash();
????????hash.put(key,?hashKey,?value);
????}
????/**
?????*?哈希獲取數(shù)據(jù)
?????*
?????*?@param?key
?????*?@param?hashKey
?????*?@return
?????*/
????public?Object?hmGet(String?key,?Object?hashKey)?{
????????HashOperations?hash?=?redisTemplate.opsForHash();
????????return?hash.get(key,?hashKey);
????}
????/**
?????*?列表添加
?????*
?????*?@param?k
?????*?@param?v
?????*/
????public?void?lPush(String?k,?Object?v)?{
????????ListOperations?list?=?redisTemplate.opsForList();
????????list.rightPush(k,?v);
????}
????/**
?????*?列表獲取
?????*
?????*?@param?k
?????*?@param?l
?????*?@param?l1
?????*?@return
?????*/
????public?List{
????????ListOperations?list?=?redisTemplate.opsForList();
????????return?list.range(k,?l,?l1);
????}
????/**
?????*?集合添加
?????*
?????*?@param?key
?????*?@param?value
?????*/
????public?void?add(String?key,?Object?value)?{
????????SetOperations?set?=?redisTemplate.opsForSet();
????????set.add(key,?value);
????}
????/**
?????*?集合獲取
?????*
?????*?@param?key
?????*?@return
?????*/
????public?Set{
????????SetOperations?set?=?redisTemplate.opsForSet();
????????return?set.members(key);
????}
????/**
?????*?有序集合添加
?????*
?????*?@param?key
?????*?@param?value
?????*?@param?scoure
?????*/
????public?void?zAdd(String?key,?Object?value,?double?scoure)?{
????????ZSetOperations?zset?=?redisTemplate.opsForZSet();
????????zset.add(key,?value,?scoure);
????}
????/**
?????*?有序集合獲取
?????*
?????*?@param?key
?????*?@param?scoure
?????*?@param?scoure1
?????*?@return
?????*/
????public?Set{
????????ZSetOperations?zset?=?redisTemplate.opsForZSet();
????????redisTemplate.opsForValue();
????????return?zset.rangeByScore(key,?scoure,?scoure1);
????}
????//第一次加載的時(shí)候?qū)?shù)據(jù)加載到redis中
????public?void?saveDataToRedis(String?name)?{
????????double?index?=?Math.abs(name.hashCode()?%?size);
????????long?indexLong?=?new?Double(index).longValue();
????????boolean?availableUsers?=?setBit("availableUsers",?indexLong,?true);
????}
????//第一次加載的時(shí)候?qū)?shù)據(jù)加載到redis中
????public?boolean?getDataToRedis(String?name)?{
????????double?index?=?Math.abs(name.hashCode()?%?size);
????????long?indexLong?=?new?Double(index).longValue();
????????return?getBit("availableUsers",?indexLong);
????}
????/**
?????*?有序集合獲取排名
?????*
?????*?@param?key?集合名稱(chēng)
?????*?@param?value?值
?????*/
????public?Long?zRank(String?key,?Object?value)?{
????????ZSetOperations?zset?=?redisTemplate.opsForZSet();
????????return?zset.rank(key,value);
????}
????/**
?????*?有序集合獲取排名
?????*
?????*?@param?key
?????*/
????public?Set>?zRankWithScore(String?key,?long?start,long?end)?{
????????ZSetOperations?zset?=?redisTemplate.opsForZSet();
????????Set>?ret?=?zset.rangeWithScores(key,start,end);
????????return?ret;
????}
????/**
?????*?有序集合添加
?????*
?????*?@param?key
?????*?@param?value
?????*/
????public?Double?zSetScore(String?key,?Object?value)?{
????????ZSetOperations?zset?=?redisTemplate.opsForZSet();
????????return?zset.score(key,value);
????}
????/**
?????*?有序集合添加分?jǐn)?shù)
?????*
?????*?@param?key
?????*?@param?value
?????*?@param?scoure
?????*/
????public?void?incrementScore(String?key,?Object?value,?double?scoure)?{
????????ZSetOperations?zset?=?redisTemplate.opsForZSet();
????????zset.incrementScore(key,?value,?scoure);
????}
????/**
?????*?有序集合獲取排名
?????*
?????*?@param?key
?????*/
????public?Set>?reverseZRankWithScore(String?key,?long?start,long?end)?{
????????ZSetOperations?zset?=?redisTemplate.opsForZSet();
????????Set>?ret?=?zset.reverseRangeByScoreWithScores(key,start,end);
????????return?ret;
????}
????/**
?????*?有序集合獲取排名
?????*
?????*?@param?key
?????*/
????public?Set>?reverseZRankWithRank(String?key,?long?start,?long?end)?{
????????ZSetOperations?zset?=?redisTemplate.opsForZSet();
????????Set>?ret?=?zset.reverseRangeWithScores(key,?start,?end);
????????return?ret;
????}
}
控制層

RedisController.java
package?com.cyb.mobile.controller;
import?com.cyb.mobile.utils.RedisUtils;
import?org.springframework.beans.factory.annotation.Autowired;
import?org.springframework.web.bind.annotation.RequestMapping;
import?org.springframework.web.bind.annotation.RestController;
/**
?*?@ClassName:TestController
?*?@Description:Redis控制器
?*?@Author:chenyb
?*?@Date:2020/8/17 12:07 上午
?*?@Versiion:1.0
?*/
@RestController
public?class?RedisController?{
????@Autowired
????private?RedisUtils?redisUtils;
????@RequestMapping("setAndGet")
????public?String?test(String?k,String?v){
????????redisUtils.set(k,v);
????????return?(String)?redisUtils.get(k);
????}
}
測(cè)試

SpringBoot整合Mybatis
添加依賴(lài)
<dependency>
????<groupId>org.mybatis.spring.bootgroupId>
????<artifactId>mybatis-spring-boot-starterartifactId>
????<version>2.1.3version>
dependency>
<dependency>
????<groupId>mysqlgroupId>
????<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
????<groupId>com.alibabagroupId>
????<artifactId>druidartifactId>
????<version>1.1.23version>
dependency>
完整pom.xml
<project?xmlns="http://maven.apache.org/POM/4.0.0"?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
????xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?https://maven.apache.org/xsd/maven-4.0.0.xsd">
????<modelVersion>4.0.0modelVersion>
????<parent>
????????<groupId>org.springframework.bootgroupId>
????????<artifactId>spring-boot-starter-parentartifactId>
????????<version>2.3.3.RELEASEversion>
????????<relativePath/>?
????parent>
????<groupId>com.cybgroupId>
????<artifactId>chenyb-mobile-redisartifactId>
????<version>0.0.1-SNAPSHOTversion>
????<name>chenyb-mobile-redisname>
????<description>Demo?project?for?Spring?Bootdescription>
????<properties>
????????<java.version>1.8java.version>
????properties>
????<dependencies>
????????<dependency>
????????????<groupId>org.springframework.bootgroupId>
????????????<artifactId>spring-boot-starter-webartifactId>
????????dependency>
????????<dependency>
????????????<groupId>org.springframework.bootgroupId>
????????????<artifactId>spring-boot-starter-testartifactId>
????????????<scope>testscope>
????????????<exclusions>
????????????????<exclusion>
????????????????????<groupId>org.junit.vintagegroupId>
????????????????????<artifactId>junit-vintage-engineartifactId>
????????????????exclusion>
????????????exclusions>
????????dependency>
????????<dependency>
????????????<groupId>io.projectreactorgroupId>
????????????<artifactId>reactor-testartifactId>
????????????<scope>testscope>
????????dependency>
????????
????????<dependency>
????????????<groupId>org.springframework.bootgroupId>
????????????<artifactId>spring-boot-starter-data-redisartifactId>
????????dependency>
????????
????????<dependency>
????????????<groupId>org.mybatis.spring.bootgroupId>
????????????<artifactId>mybatis-spring-boot-starterartifactId>
????????????<version>2.1.3version>
????????dependency>
????????
????????<dependency>
????????????<groupId>mysqlgroupId>
????????????<artifactId>mysql-connector-javaartifactId>
????????dependency>
????????
????????<dependency>
????????????<groupId>com.alibabagroupId>
????????????<artifactId>druidartifactId>
????????????<version>1.1.23version>
????????dependency>
????dependencies>
????<build>
????????<plugins>
????????????<plugin>
????????????????<groupId>org.springframework.bootgroupId>
????????????????<artifactId>spring-boot-maven-pluginartifactId>
????????????plugin>
????????plugins>
????build>
project>
設(shè)置配置文件
application.properties
#?連接的那個(gè)數(shù)據(jù)庫(kù)
spring.redis.database=0
#?redis服務(wù)的ip地址
spring.redis.host=192.168.199.142
#?redis端口號(hào)
spring.redis.port=6379
#?redis的密碼,沒(méi)設(shè)置過(guò)密碼,可為空
spring.redis.password=12345678
#?端口號(hào)
server.port=8081
#?========================數(shù)據(jù)庫(kù)相關(guān)配置=====================
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/nba?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
#?使用阿里巴巴druid數(shù)據(jù)源,默認(rèn)使用自帶
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#開(kāi)啟控制臺(tái)打印sql
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#?mybatis?下劃線轉(zhuǎn)駝峰配置,兩者都可以
#?mybatis.configuration.mapUnderscoreToCamelCase=true
mybatis.configuration.map-underscore-to-camel-case=true
#?配置掃描
mybatis.mapper-locations=classpath:mapper/*.xml
#?實(shí)體類(lèi)所在的包別名
mybatis.type-aliases-package=com.cyb.mobile.domain
啟動(dòng)類(lèi)上添加掃描路徑

NbaPlayer.java(實(shí)體類(lèi))

NbaPlayerMapper.xml

mapper
????????PUBLIC?"-//mybatis.org//DTD?Mapper?3.0//EN"
????????"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper?namespace="com.cyb.mobile.mapper.NbaPlayerMapper">
????<select?id="ListNbaPlayer"?resultType="NbaPlayer">
????????SELECT?*?FROM?nba_player
????select>
mapper>
NbaPlayerMapper.java

NbaPlayerService.java

NbaPlayerServiceImpl.java

控制器(Controller)

測(cè)試

redis作為mybatis緩存
用戶(hù)第一次訪問(wèn)的時(shí)候獲取數(shù)據(jù)庫(kù)的值,再次訪問(wèn)時(shí)直接從緩存中獲取數(shù)據(jù)
設(shè)置緩存過(guò)期時(shí)間
代碼演示
添加FastJSON依賴(lài)
<dependency>
????<groupId>com.alibabagroupId>
????<artifactId>fastjsonartifactId>
????<version>1.2.73version>
dependency>
~
@RequestMapping("test")
public?Object?test(){
????//step1?先從redis中取
????String?strJson=(String)?redisUtils.get("nbaPlayerCache");
????if?(strJson==null){
????????System.out.println("從db取值");
????????//?step2如果拿不到則從DB取值
???????List?listNbaPlayer=nbaPlayerService.ListNbaPlayer();
???????//?step3?DB非空情況刷新redis值
???????if?(listNbaPlayer!=null){
???????????redisUtils.set("nbaPlayerCache",?JSON.toJSONString(listNbaPlayer));
???????????return?listNbaPlayer;
???????}
???????return?null;
????}else
????{
????????System.out.println("從redis緩存取值");
????????return?JSONObject.parseArray(strJson,NbaPlayer.class);
????}
}
注意
項(xiàng)目8080是對(duì)外端口(向外部暴露的端口),區(qū)別于內(nèi)部進(jìn)程號(hào),查內(nèi)部端口用ps -ef|grep port,查外部端口用lsof -i:port


壓測(cè)工具
上面我們已經(jīng)SpringBoot整合Redis和Mybatis,但是無(wú)法知道具體QPS多少,此時(shí)我們可以使用壓測(cè)工具來(lái)測(cè)壓,參考:
https://www.cnblogs.com/chenyanbin/p/13332068.html
資料下載
鏈接:?https://pan.baidu.com/s/1d4xwXVfA6dYHvLFxha59Kg?? 密碼:?bff7
公眾號(hào)回復(fù)“0217”獲取封面原圖
點(diǎn)擊關(guān)注公眾號(hào)↑↑
評(píng)論
圖片
表情
