16. 尚融宝后台引入Redis存储数据字典

一、简介

1、场景

由于数据字典的变化不是很频繁,而且系统对数据字典的访问较频繁,所以我们有必要把数据字典的数据存入缓存,减少数据库压力和提高访问速度。这里,我们使用Redis作为系统的分布式缓存中间件。

2、RedisTemplate

在Spring Boot项目中中,默认集成Spring Data Redis,Spring Data Redis针对Redis提供了非常方便的操作模版RedisTemplate,并且可以进行连接池自动管理。

二、引入Redis

1、项目中集成Redis

service-base模块中添加redis依赖,Spring Boot 2.0以上默认通过commons-pool2连接池连接Redis

		
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-data-redisartifactId>
		dependency>
		
		<dependency>
			<groupId>org.apache.commonsgroupId>
			<artifactId>commons-pool2artifactId>
		dependency>

		
		<dependency>
			<groupId>com.fasterxml.jackson.coregroupId>
			<artifactId>jackson-databindartifactId>
		dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.datatypegroupId>
			<artifactId>jackson-datatype-jsr310artifactId>
		dependency>

2、添加Redis连接配置

service-core 模块的 application.yml 中添加如下配置

#spring: 
  redis:
    host: 192.168.2.190
    port: 6379
    database: 0
    #password: 123456 # 密码为空,不需要加这个字段
    timeout: 3000ms #最大等待时间,超时则抛出异常,否则请求一直等待
    lettuce:
      pool:
        max-active: 20  #最大连接数,负值表示没有限制,默认8
        max-wait: -1    #最大阻塞等待时间,负值表示没限制,默认-1
        max-idle: 8     #最大空闲连接,默认8
        min-idle: 0     #最小空闲连接,默认0

16. 尚融宝后台引入Redis存储数据字典_第1张图片

3、启动Redis服务

远程连接Linux服务器

# 普通方式
cd /usr/local/redis-5.0.8
bin/redis-server redis.conf

# docker方式
docker run -d -p 6379:6379 --name myredis redis:5.0.8

三、测试RedisTemplate

1、存值测试

service-core模块

test目录下创建测试类

RedisTemplateTests.java

package com.indi.srb.core;

@SpringBootTest
@RunWith(SpringRunner.class)
public class RedisTemplateTests {
     
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private DictMapper dictMapper;
    
    @Test
    public void saveDict(){
     
        Dict dict = dictMapper.selectById(1);
        //向数据库中存储string类型的键值对, 过期时间5分钟
        redisTemplate.opsForValue().set("dict", dict, 5, TimeUnit.MINUTES);
    }
}

发现RedisTemplate默认使用了JDK的序列化方式存储了key和value,不易于使用,需要添加序列化配置。

2、Redis配置文件

service-base 模块config包下

创建RedisConfig.java,在这个配置文件中配置Redis序列化方案

package com.indi.srb.base.config;

@Configuration
public class RedisConfig {
     
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
     

        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 设置连接池工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        //首先解决key的序列化方式
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);

        //解决value的序列化方式
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);

        ObjectMapper objectMapper = new ObjectMapper();
        //objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        //序列化时将类的数据类型存入json,以便反序列化的时候转换成正确的类型
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);

        // 解决jackson2无法反序列化LocalDateTime的问题
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());

        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        return redisTemplate;
    }
}

再次测试,key使用了字符串存储,value使用了json存储

3、取值测试

    @Test
    public void getDict(){
     
        Dict dict = (Dict)redisTemplate.opsForValue().get("dict");
        System.out.println(dict);
    }

四、将数据字典存入Redis

当redis服务器宕机时,不要抛出异常,要正常的执行后面的流程,使业务可以正常的运行

service-core模块service.impl包下

修改DictServiceImpl.java

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public List<Dict> listByParentId(Long parentId) {
     
        List<Dict> dictList = null;
        try {
     
            dictList = (List<Dict>) redisTemplate.opsForValue().get("srb:core:dictList:" + parentId);
            if (dictList != null) {
     
                log.info("来自redis的数据");
                return dictList;
            }
        } catch (Exception e) {
     
            log.error("读取redis失败:" + ExceptionUtils.getStackTrace(e));
        }

        log.info("从数据库查询数据");
        QueryWrapper<Dict> queryWrapper = new QueryWrapper<Dict>().eq("parent_id", parentId);
        dictList = baseMapper.selectList(queryWrapper);
        dictList.forEach(dict -> {
     
            dict.setHasChildren(this.hasChildren(dict.getId()));
        });

        try {
     
            redisTemplate.opsForValue().set("srb:core:dictList:" + parentId, dictList, 5, TimeUnit.MINUTES);
            log.info("存入redis成功");
        } catch (Exception e) {
     
            log.error("存入redis失败:" + ExceptionUtils.getStackTrace(e));
        }
        return dictList;
    }

16. 尚融宝后台引入Redis存储数据字典_第2张图片

16. 尚融宝后台引入Redis存储数据字典_第3张图片

五、测试

第一次,刚进入数据字典

在这里插入图片描述
在这里插入图片描述
16. 尚融宝后台引入Redis存储数据字典_第4张图片

进入二级菜单

在这里插入图片描述
在这里插入图片描述
16. 尚融宝后台引入Redis存储数据字典_第5张图片

第二次,刷新页面,重新进入字典,直接走redis缓存了
在这里插入图片描述
再进入二级菜单,也是直接走缓存,测试成功!
在这里插入图片描述

你可能感兴趣的:(#,尚融宝后台,redis)