前言 個人網站使用Vue作為前端,SpringBoot作為後端,MySQL作為資料庫,但前端每次請求都會從MySQL資料庫中讀取數據,而MySQL資料庫的數據是存儲於伺服器磁碟中,所以響應速度有一定影響。之前瞭解過一點Redis資料庫,該資料庫數據存儲於記憶體中(也可以持久化於磁碟中),數據讀取速度就 ...
前言
個人網站使用Vue作為前端,SpringBoot作為後端,MySQL作為資料庫,但前端每次請求都會從MySQL資料庫中讀取數據,而MySQL資料庫的數據是存儲於伺服器磁碟中,所以響應速度有一定影響。之前瞭解過一點Redis資料庫,該資料庫數據存儲於記憶體中(也可以持久化於磁碟中),數據讀取速度就會比存儲於磁碟中的MySQL快很多,故想把Redis資料庫應用於該網站項目中。
一、安裝Redis
Linux系統安裝Redis比較簡單,可以直接通過命令行安裝,安裝過程比較簡單,在此就不贅述,下列出一些常用命令
# 更新apt
sudo apt update
# 安裝Redis
sudo apt-get install redis-server
# 設置密碼(在配置文件redis.conf中,位置在 /etc/redis/redis.conf)
requirepass ******
# 啟動Redis服務
service redis-server start
# 停止Redis服務
service redis-server stop
# 重啟Redis服務
service redis-server restart
# 啟動Redis客戶端
redis-cli
# 測試Redis是否連接
127.0.0.1:6379> ping
註意:需要修改Redis配置文件中的保護模式“protected-mode"為修改為no,否則會出現無法連接的情況
# 修改保護模式為no
# protected-mode yes
protected-mode no
# 若不修改可能無法連接Redis,出現以下錯誤
org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:6379
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1689)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1597)
······
······
······
Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:6379
at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78)
at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56)
······
······
······
Caused by: java.lang.IllegalStateException: RedisHandshakeHandler not registered
at io.lettuce.core.AbstractRedisClient.lambda$initializeChannelAsync0$6(AbstractRedisClient.java:431)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:590)
······
······
······
二、SpringBoot項目集成Redis
1、pom.xml添加依賴
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、Redis資料庫連接配置 application.yml
# Redis
redis:
# 伺服器地址
host: 127.0.0.1
# 伺服器埠號
port: 6379
# 使用的資料庫索引
database: 0
# 連接超時時間
timeout: 10000
# 設置密碼
password: ******
lettuce:
# 連接池
pool:
# 最大阻塞等待時間,負數表示沒有限制
max-wait: -1
# 連接池中最大空閑
max-idle: 5
# 連接池中最小空閑
min-idle: 0
# 連接池最大連接數
max-active: 20
3、Redis配置類RedisConfig
package cn.huskysir.Config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
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.*;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching //開啟註解
public class RedisConfig extends CachingConfigurerSupport {
/**
* retemplate相關配置
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 配置連接工廠
template.setConnectionFactory(factory);
//使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(預設使用JDK的序列化方式)
Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域,field,get和set,以及修飾符範圍,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化輸入的類型,類必須是非final修飾的,final修飾的類,比如String,Integer等會跑出異常
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSeial.setObjectMapper(om);
// 值採用json序列化
template.setValueSerializer(jacksonSeial);
//使用StringRedisSerializer來序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
// 設置hash key 和value序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jacksonSeial);
template.afterPropertiesSet();
return template;
}
/**
* 對hash類型的數據操作
*/
@Bean
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForHash();
}
/**
* 對redis字元串類型數據操作
*/
@Bean
public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForValue();
}
/**
* 對鏈表類型的數據操作
*/
@Bean
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForList();
}
/**
* 對無序集合類型的數據操作
*/
@Bean
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForSet();
}
/**
* 對有序集合類型的數據操作
*/
@Bean
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForZSet();
}
}
4、Redis工具類RedisUtil
package cn.huskysir.Utils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtil {
@Resource
private RedisTemplate<String, Object> redisTemplate;
public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 指定緩存失效時間
*
* @param key 鍵
* @param time 時間(秒)
* @return
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根據key 獲取過期時間
*
* @param key 鍵 不能為null
* @return 時間(秒) 返回0代表為永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判斷key是否存在
*
* @param key 鍵
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 刪除緩存
*
* @param key 可以傳一個值 或多個
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
}
}
}
//============================String=============================
/**
* 普通緩存獲取
*
* @param key 鍵
* @return 值
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通緩存放入
*
* @param key 鍵
* @param value 值
* @return true成功 false失敗
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通緩存放入並設置時間
*
* @param key 鍵
* @param value 值
* @param time 時間(秒) time要大於0 如果time小於等於0 將設置無限期
* @return true成功 false 失敗
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 遞增
*
* @param key 鍵
* @param delta 要增加幾(大於0)
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("遞增因數必須大於0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 遞減
*
* @param key 鍵
* @param delta 要減少幾(小於0)
* @return
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("遞減因數必須大於0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
//================================Map=================================
/**
* HashGet
*
* @param key 鍵 不能為null
* @param item 項 不能為null
* @return 值
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 獲取hashKey對應的所有鍵值
*
* @param key 鍵
* @return 對應的多個鍵值
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
*
* @param key 鍵
* @param map 對應多個鍵值
* @return true 成功 false 失敗
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 並設置時間
*
* @param key 鍵
* @param map 對應多個鍵值
* @param time 時間(秒)
* @return true成功 false失敗
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一張hash表中放入數據,如果不存在將創建
*
* @param key 鍵
* @param item 項
* @param value 值
* @return true 成功 false失敗
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一張hash表中放入數據,如果不存在將創建
*
* @param key 鍵
* @param item 項
* @param value 值
* @param time 時間(秒) 註意:如果已存在的hash表有時間,這裡將會替換原有的時間
* @return true 成功 false失敗
*/
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 刪除hash表中的值
*
* @param key 鍵 不能為null
* @param item 項 可以使多個 不能為null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判斷hash表中是否有該項的值
*
* @param key 鍵 不能為null
* @param item 項 不能為null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash遞增 如果不存在,就會創建一個 並把新增後的值返回
*
* @param key 鍵
* @param item 項
* @param by 要增加幾(大於0)
* @return
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash遞減
*
* @param key 鍵
* @param item 項
* @param by 要減少記(小於0)
* @return
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
//============================set=============================
/**
* 根據key獲取Set中的所有值
*
* @param key 鍵
* @return
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根據value從一個set中查詢,是否存在
*
* @param key 鍵
* @param value 值
* @return true 存在 false不存在
*/
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 將數據放入set緩存
*
* @param key 鍵
* @param values 值 可以是多個
* @return 成功個數
*/
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 將set數據放入緩存
*
* @param key 鍵
* @param time 時間(秒)
* @param values 值 可以是多個
* @return 成功個數
*/
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0) {
expire(key, time);
}
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 獲取set緩存的長度
*
* @param key 鍵
* @return
*/
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 移除值為value的
*
* @param key 鍵
* @param values 值 可以是多個
* @return 移除的個數
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//===============================list=================================
/**
* 獲取list緩存的內容
*
* @param key 鍵
* @param start 開始
* @param end 結束 0 到 -1代表所有值
* @return
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 獲取list緩存的長度
*
* @param key 鍵
* @return
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 通過索引 獲取list中的值
*
* @param key 鍵
* @param index 索引 index>=0時, 0 表頭,1 第二個元素,依次類推;index<0時,-1,表尾,-2倒數第二個元素,依次類推
* @return
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 將list放入緩存
*
* @param key 鍵
* @param value 值
* @return
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 將list放入緩存
*
* @param key 鍵
* @param value 值
* @param time 時間(秒)
* @return
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 將list放入緩存
*
* @param key 鍵
* @param value 值
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 將list放入緩存
*
* @param key 鍵
* @param value 值
* @param time 時間(秒)
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根據索引修改list中的某條數據
*
* @param key 鍵
* @param index 索引
* @param value 值
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N個值為value
*
* @param key 鍵
* @param count 移除多少個
* @param value 值
* @return 移除的個數
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}
三、SpringBoot項目集成log4j2
SpringBoot項目在運行的時候可能會產生一些運行信息,如果能將這些信息記錄下來,那麼對於該項目的運行狀態以及錯誤排查會起到一個非常好的幫助,所以採用log4j2進行日誌記錄
1、pom.xml添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- 排除自帶的logback依賴 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
2、log4j2.xml配置文件,放置於resources文件夾下
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="fatal">
<Properties>
<Property name="baseDir" value="/home/leilee/Projects/back/logs"/>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<!--控制台只輸出level及以上級別的信息(onMatch),其他的直接拒絕(onMismatch) -->
<ThresholdFilter level="info" onMatch="ACCEPT"
onMismatch="DENY"/>
<PatternLayout
pattern="[%d{MM:dd HH:mm:ss.SSS}] [%level] [%logger{36}] - %msg%n"/>
</Console>
<!--debug級別日誌文件輸出-->
<RollingFile name="debug_appender" fileName="${baseDir}/debug.log"
filePattern="${baseDir}/debug_%i.log.%d{yyyy-MM-dd}">
<!-- 過濾器 -->
<Filters>
<!-- 限制日誌級別在debug及以上在info以下 -->
<ThresholdFilter level="debug"/>
<ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>
<!-- 日誌格式 -->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!-- 策略 -->
<Policies>
<!-- 每隔一天轉存 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<!-- 文件大小 -->
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<!-- info級別日誌文件輸出 -->
<RollingFile name="info_appender" fileName="${baseDir}/info.log"
filePattern="${baseDir}/info_%i.log.%d{yyyy-MM-dd}">
<!-- 過濾器 -->
<Filters>
<!-- 限制日誌級別在info及以上在error以下 -->
<ThresholdFilter level="info"/>
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>
<!-- 日誌格式 -->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!-- 策略 -->
<Policies>
<!-- 每隔一天轉存 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<!-- 文件大小 -->
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<!-- error級別日誌文件輸出 -->
<RollingFile name="error_appender" fileName="${baseDir}/error.log"
filePattern="${baseDir}/error_%i.log.%d{yyyy-MM-dd}">
<!-- 過濾器 -->
<Filters>
<!-- 限制日誌級別在error及以上 -->
<ThresholdFilter level="error"/>
</Filters>
<!-- 日誌格式 -->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<!-- 每隔一天轉存 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<!-- 文件大小 -->
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console"/>
<AppenderRef ref="debug_appender"/>
<AppenderRef ref="info_appender"/>
<AppenderRef ref="error_appender"/>
</Root>
</Loggers>
</Configuration>
註意:第四行中value的值即輸出的log文件的存放路徑
3、自定義log信息
如果自己想存入一些自定義的信息,那麼採用@Log4j2對類進行註解,然後在類中使用log的方法即可,以該網站的資料庫讀取過程為例
package cn.huskysir.Service.Impl;
import cn.huskysir.Dao.DynastyMapper;
import cn.huskysir.Dao.EmperorMapper;
import cn.huskysir.Entity.MySQL.Dynasty;
import cn.huskysir.Entity.MySQL.Emperor;
import cn.huskysir.Service.EmperorService;
import cn.huskysir.Utils.RedisUtil;
import cn.huskysir.Vo.EmperorVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
/**
* Emperor Service層(實現類)
*/
@Log4j2
@Service
public class EmperorServiceImpl implements EmperorService {
@Resource
EmperorMapper emperorMapper;
@Resource
DynastyMapper dynastyMapper;
@Resource
RedisUtil redisUtil;
/**
* 獲得所有EmperorVo對象列表
*
* @return
*/
@Override
public List<EmperorVo> getAllEmperorVoList() {
// 判斷Redis是否存在該結果
String key = "getAllEmperorVoList";
if (redisUtil.hasKey(key)) {
List<EmperorVo> emperorVoList = (List<EmperorVo>) redisUtil.get(key);
System.out.println("由Redis得到" + key + "結果");
// 日誌記錄
log.info(new Date() + " 由Redis得到" + key + "數據");
return emperorVoList;
}
List<Emperor> emperorList = emperorMapper.selectList(null);
List<EmperorVo> emperorVoList = new LinkedList<>();
for (Emperor emperor : emperorList) {
EmperorVo emperorVo = new EmperorVo();
BeanUtils.copyProperties(emperor, emperorVo);
Dynasty dynasty = dynastyMapper.selectById(emperor.getDynastyId());
emperorVo.setDynastyName(dynasty.getName());
emperorVo.calculateTime();
emperorVoList.add(emperorVo);
}
System.out.println("由MySQL得到" + key + "結果");
// 日誌記錄
log.info(new Date() + " 由MySQL得到" + key + "數據");
if (redisUtil.set(key, emperorVoList, 600)) {
System.out.println("Redis已存入" + key + "數據");
// 日誌記錄
log.info(new Date() + " Redis已存入" + key + "數據");
}
return emperorVoList;
}
/**
* 根據id獲得EmperorVo對象
*
* @param id
* @return
*/
@Override
public EmperorVo getEmperorVoById(Integer id) {
// 判斷Redis是否存在該結果
String key = "getEmperorVoById_" + String.valueOf(id);
if (redisUtil.hasKey(key)) {
EmperorVo emperorVo = (EmperorVo) redisUtil.get(key);
System.out.println("由Redis得到" + key + "結果");
// 日誌記錄
log.info(new Date() + " 由Redis得到" + key + "數據");
return emperorVo;
}
Emperor emperor = emperorMapper.selectById(id);
EmperorVo emperorVo = new EmperorVo();
BeanUtils.copyProperties(emperor, emperorVo);
Dynasty dynasty = dynastyMapper.selectById(emperor.getDynastyId());
emperorVo.setDynastyName(dynasty.getName());
emperorVo.calculateTime();
System.out.println("由MySQL得到" + key + "結果");
// 日誌記錄
log.info(new Date() + " 由MySQL得到" + key + "數據");
if (redisUtil.set(key, emperorVo, 600)) {
System.out.println("Redis已存入" + key + "數據");
// 日誌記錄
log.info(new Date() + " Redis已存入" + key + "數據");
}
return emperorVo;
}
/**
* 根據dynastyId獲得所有EmperorVo對象列表
*
* @param dynastyId
* @return
*/
@Override
public List<EmperorVo> getEmperorListByDynastyId(Integer dynastyId) {
// 判斷Redis是否存在該結果
String key = "getEmperorListByDynastyId_" + String.valueOf(dynastyId);
if (redisUtil.hasKey(key)) {
List<EmperorVo> emperorVoList = (List<EmperorVo>) redisUtil.get(key);
System.out.println("由Redis得到" + key + "結果");
// 日誌記錄
log.info(new Date() + " 由Redis得到" + key + "數據");
return emperorVoList;
}
QueryWrapper<Emperor> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("dynasty_id", dynastyId);
List<Emperor> emperorList = emperorMapper.selectList(queryWrapper);
List<EmperorVo> emperorVoList = new LinkedList<>();
String nastyName = dynastyMapper.selectById(dynastyId).getName();
for (Emperor emperor : emperorList) {
EmperorVo emperorVo = new EmperorVo();
BeanUtils.copyProperties(emperor, emperorVo);
emperorVo.setDynastyName(nastyName);
emperorVo.calculateTime();
emperorVoList.add(emperorVo);
}
System.out.println("由MySQL得到" + key + "結果");
// 日誌記錄
log.info(new Date() + " 由MySQL得到" + key + "數據");
if (redisUtil.set(key, emperorVoList, 600)) {
System.out.println("Redis已存入" + key + "數據");
// 日誌記錄
log.info(new Date() + " Redis已存入" + key + "數據");
}
return emperorVoList;
}
}
以“getEmperorListByDynastyId(Integer dynastyId)”方法為例,該方法是根據dynastyId獲得List
該網站後臺的info.log日誌記錄如下
[00:54:31:770] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:141) - Wed Sep 20 00:54:31 CST 2023 由MySQL得到getEmperorListByDynastyId_1數據
[00:54:31:773] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:145) - Wed Sep 20 00:54:31 CST 2023 Redis已存入getEmperorListByDynastyId_1數據
[00:54:35:853] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:141) - Wed Sep 20 00:54:35 CST 2023 由MySQL得到getEmperorListByDynastyId_2數據
[00:54:35:863] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:145) - Wed Sep 20 00:54:35 CST 2023 Redis已存入getEmperorListByDynastyId_2數據
[00:54:37:363] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:123) - Wed Sep 20 00:54:37 CST 2023 由Redis得到getEmperorListByDynastyId_1數據
[00:54:38:043] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:123) - Wed Sep 20 00:54:38 CST 2023 由Redis得到getEmperorListByDynastyId_2數據
[00:54:39:214] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:123) - Wed Sep 20 00:54:39 CST 2023 由Redis得到getEmperorListByDynastyId_1數據
[00:54:39:936] [INFO] - cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:123) - Wed Sep 20 00:54:39 CST 2023 由Redis得到getEmperorListByDynastyId_2數據
四、總結
關於SpringBoot項目配置Redis與log4j2是查詢官方文檔以及他人博客得到的,本文中的Redis配置類、Redis工具類以及log4j2.xml配置文件來自網路,查證源自何處比較麻煩,所以在此感謝所有人的分享!
弱小和無知不是生存的障礙,傲慢才是。