汕尾海湾 发表于 2023-9-25 01:47:04

Linux服务器使用Redis作为数据缓存,并用log4j2进行日志记录

前言
个人网站使用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添加依赖

<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: 203、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);
            } 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>
      
      <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
      </exclusion>
    </exclusions>
</dependency>


<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">
            
            <ThresholdFilter level="info" onMatch="ACCEPT"
                           onMismatch="DENY"/>
            <PatternLayout
                  pattern="[%d{MM:dd HH:mm:ss.SSS}] [%level] [%logger{36}] - %msg%n"/>
      </Console>

      
      <RollingFile name="debug_appender" fileName="${baseDir}/debug.log"
                     filePattern="${baseDir}/debug_%i.log.%d{yyyy-MM-dd}">
            
            <Filters>
               
                <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>

      
      <RollingFile name="info_appender" fileName="${baseDir}/info.log"
                     filePattern="${baseDir}/info_%i.log.%d{yyyy-MM-dd}">
            
            <Filters>
               
                <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>

      
      <RollingFile name="error_appender" fileName="${baseDir}/error.log"
                     filePattern="${baseDir}/error_%i.log.%d{yyyy-MM-dd}">
            
            <Filters>
               
                <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对象,首先会根据方法名及dynastyId在Redis数据库中查找,若存在则直接返回,否则从MySQL数据库中读取,并将结果存入Redis数据库中然后返回。使用log.info()记录数据库读取过程,该记录会存储于info.log文件中
该网站后台的info.log日志记录如下
- cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:141) - Wed Sep 20 00:54:31 CST 2023 由MySQL得到getEmperorListByDynastyId_1数据
- cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:145) - Wed Sep 20 00:54:31 CST 2023 Redis已存入getEmperorListByDynastyId_1数据
- cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:141) - Wed Sep 20 00:54:35 CST 2023 由MySQL得到getEmperorListByDynastyId_2数据
- cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:145) - Wed Sep 20 00:54:35 CST 2023 Redis已存入getEmperorListByDynastyId_2数据
- cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:123) - Wed Sep 20 00:54:37 CST 2023 由Redis得到getEmperorListByDynastyId_1数据
- cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:123) - Wed Sep 20 00:54:38 CST 2023 由Redis得到getEmperorListByDynastyId_2数据
- cn.huskysir.Service.Impl.EmperorServiceImpl.getEmperorListByDynastyId(EmperorServiceImpl.java:123) - Wed Sep 20 00:54:39 CST 2023 由Redis得到getEmperorListByDynastyId_1数据
- 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配置文件来自网络,查证源自何处比较麻烦,所以在此感谢所有人的分享!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: Linux服务器使用Redis作为数据缓存,并用log4j2进行日志记录