xustudyxu's Blog
首页​
导航🚀​
  • 数据结构
  • 计算机网络
  • Java基础

    • JavaSE
  • JavaWeb

    • HTML
    • CSS
    • JavaScript
    • Vue
    • Servlet
    • MVC
    • filter|listener
  • Spring5
  • SpringMVC
  • SpringBoot2
  • SpringCloud
  • SpringSecurity
  • 搜索引擎

    • ElasticSearch
  • 消息队列

    • RabbitMQ
  • 服务器

    • Nginx🌐
  • 服务框架

    • Dubbo
  • Python

    • Python基础
    • 数据分析
  • 环境搭建

    • Hadoop集群
    • KVM虚拟化技术
  • SQL 数据库

    • MySQL
  • NoSQL 数据库

    • NoSQL数据库概论
    • Redis
    • MongoDB
    • HBase
  • 框架

    • MyBatis
    • MyBatis-Plus
  • 部署

    • Linux
    • Docker
  • 管理

    • Maven
    • Git
  • 十大排序算法
  • 力扣算法题
  • 初级开发篇
  • 中高进阶篇
  • 友情链接
  • 优秀博客文章
  • 索引

    • 分类
    • 标签
    • 归档
  • 其他

    • 关于
查看源码 (opens new window)

xustudyxu

一起学习编程!
首页​
导航🚀​
  • 数据结构
  • 计算机网络
  • Java基础

    • JavaSE
  • JavaWeb

    • HTML
    • CSS
    • JavaScript
    • Vue
    • Servlet
    • MVC
    • filter|listener
  • Spring5
  • SpringMVC
  • SpringBoot2
  • SpringCloud
  • SpringSecurity
  • 搜索引擎

    • ElasticSearch
  • 消息队列

    • RabbitMQ
  • 服务器

    • Nginx🌐
  • 服务框架

    • Dubbo
  • Python

    • Python基础
    • 数据分析
  • 环境搭建

    • Hadoop集群
    • KVM虚拟化技术
  • SQL 数据库

    • MySQL
  • NoSQL 数据库

    • NoSQL数据库概论
    • Redis
    • MongoDB
    • HBase
  • 框架

    • MyBatis
    • MyBatis-Plus
  • 部署

    • Linux
    • Docker
  • 管理

    • Maven
    • Git
  • 十大排序算法
  • 力扣算法题
  • 初级开发篇
  • 中高进阶篇
  • 友情链接
  • 优秀博客文章
  • 索引

    • 分类
    • 标签
    • 归档
  • 其他

    • 关于
查看源码 (opens new window)
  • 十大排序算法

    • 十大经典排序算法
  • 面试题

    • Java 面试题
  • 力扣算法题

    • LeetCode 算法题
  • SSM-CRUD

    • SSM-CRUD
  • SpringBoot+MyBatis-plus

    • 瑞吉外卖-介绍
    • 瑞吉外卖-员工管理
    • 瑞吉外卖-分类管理业务开发
    • 瑞吉外卖-菜品管理业务开发
    • 瑞吉外卖-套餐管理业务开发
    • 瑞吉外卖-移动端开发
    • 瑞吉外卖-移动端业务开发
    • 瑞吉外卖-功能补充
    • 瑞吉外卖-缓存优化
  • 高级宝典

    • 尚医通-项目概述
    • 尚医通-搭建环境
    • 尚医通-后台接口
    • 尚医通-前端知识点
    • 尚医通-数据字典
    • 尚医通-MongoDB
    • 尚医通-数据接口
    • 尚医通-后台系统
    • 尚医通-技术点-整合服务网关
    • 尚医通-客户端平台
    • 尚医通-手机登录
    • 尚医通-微信登录
    • 尚医通- 阿里云OSS、用户认证与就诊人
    • 尚医通-预约挂号
  • baodian
  • high
  • SYT
xu
2022-10-23
目录

尚医通-数据字典

# 尚医通-数据字典

  • 数据字典介绍
    • 页面效果
    • 表设计
    • 数据分析
  • 数据字典开发
    • 搭建 service-cmn 模块
  • 数据字典列表
    • 数据字典列表接口
  • EasyExcel 介绍
    • EasyExcel 集成
  • 数据字典导出
    • 导出接口封装
  • 数据字典导入
    • 导入接口封装
  • Spring Cache + Redis 缓存数据
    • 项目集成Spring Cache + Redis
  • 使用Spring Cache
    • 常用缓存标签
    • 数据字典应用
  • 配置Nginx

# 数据字典介绍

何为数据字典?数据字典就是管理系统常用的分类数据或者一些固定数据,例如:省市区三级联动数据、民族数据、行业数据、学历数据等,由于该系统大量使用这种数据,所以我们要做一个数据管理方便管理系统数据,一般系统基本都会做数据管理。

# 页面效果

image

# 表设计

image

# 数据分析

image

parent_id:

上级id,通过id与parent_id构建上下级关系,例如:我们要获取所有行业数据,那么只需要查询parent_id=20000的数据

name:名称,例如:填写用户信息,我们要select标签选择民族,“汉族”就是数据字典的名称

value:值,例如:填写用户信息,我们要select标签选择民族,“1”(汉族的标识)就是数据字典的值

dict_code:编码,编码是我们自定义的,全局唯一,例如:我们要获取行业数据,我们可以通过parent_id获取,但是parent_id是不确定的,所以我们可以根据编码来获取行业数据

说明:系统中会使用省市区三级联动数据,该数据我们来自“国家统计局”官方数据,地址:

http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2019/index.html

# 数据字典开发

# 搭建 service-cmn 模块

修改pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>service</artifactId>
        <groupId>com.frx01</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>service_cmn</artifactId>
    <packaging>jar</packaging>
    <name>service-cmn</name>
    <description>service-cmn</description>
    <dependencies>
    </dependencies>
    <build>
        <finalName>service-cmn</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  1. 添加配置文件application.properties
# 服务端口
server.port=8202
# 服务名
spring.application.name=service-cmn
# 环境设置:dev、test、prod
spring.profiles.active=dev
# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/yygh_cmn?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=hsp
#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  1. 添加主启动类
@SpringBootApplication
public class ServiceCmnApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceCmnApplication.class,args);
    }
}
1
2
3
4
5
6

# 数据字典列表

根据element组件要求,返回列表数据必须包含hasChildren字典,如图:

https://element.eleme.cn/#/zh-CN/component/table

image

# 数据字典列表接口

# model模块添加数据字典实体

在model模块查看实体:Dict

@Data
@ApiModel(description = "数据字典")
@TableName("dict")
public class Dict extends BaseEntity {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "上级id")
    @TableField("parent_id")
    private Long parentId;
    @ApiModelProperty(value = "名称")
    @TableField("name")
    private String name;
    @ApiModelProperty(value = "值")
    @TableField("value")
    private String value;
    @ApiModelProperty(value = "编码")
    @TableField("dict_code")
    private String dictCode;
    @ApiModelProperty(value = "是否包含子节点")
    @TableField(exist = false)
    private boolean hasChildren;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

说明:hasChildren为树形组件所需字典,标识为数据库表不存在该字段

# 添加数据字典 mapper

public interface DictMapper extends BaseMapper<Dict> {
}
1
2

# 添加数据字典 service

public interface DictService extends IService<Dict> {
    //根据数据id查询子数据列表
    List<Dict> findChildData(Long id);
}
1
2
3
4
5
  • 添加实现类
@Service
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements DictService {
    @Override
    public List<Dict> findChildData(Long id) {
        QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id",id);
        List<Dict> list = baseMapper.selectList(queryWrapper);
        //向list集合中每个dict对象中设置hasChildren
        for (Dict dict : list) {
            Long dictId = dict.getId();
            boolean isChild = this.isChildren(dictId);
            dict.setHasChildren(isChild);
        }
        return list;
    }
    //判断id下面是否有子数据
    private boolean isChildren(Long id){
        QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id",id);
        Integer count = baseMapper.selectCount(queryWrapper);
        return count>0;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 添加控制层Controller

@Api(value = "数据字典的接口")
@RestController
@RequestMapping("/admin/cmn/dict")
public class DictController {
    @Autowired
    private DictService dictService;
    //根据数据id查询子数据列表
    @ApiOperation(value = "根据数据id查询子数据列表")
    @GetMapping("/findChildData/{id}")
    public Result findChildData(@PathVariable Long id){
        List<Dict> list = dictService.findChildData(id);
        return Result.ok(list);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# EasyExcel 介绍

Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便。

EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。

文档地址:https://alibaba-easyexcel.github.io/index.html (opens new window)

github地址:https://github.com/alibaba/easyexcel (opens new window)

# EasyExcel 集成

# 添加依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>2.1.1</version>
    </dependency>
</dependencies>
1
2
3
4
5
6
7
8
Test
@Data
public class UserData {
    @ExcelProperty(value = "用户编号",index = 0)
    private int uid;
    @ExcelProperty(value = "用户名称",index = 1)
    private String username;
}
1
2
3
4
5
6
7
8
9
10
public class TestWrite {
    public static void main(String[] args) {
        //构建数据List集合
        ArrayList<Object> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            UserData data = new UserData();
            data.setUid(i);
            data.setUsername("Lucy"+i);
            list.add(data);
        }
        String fileName = "F:\\excel\\01.xlsx";
        EasyExcel.write(fileName,UserData.class).sheet("用户信息")
                .doWrite(list);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

测试成功

image

public class ExcelListener extends AnalysisEventListener<UserData> {
    //从第二行开始,一行一行去读取Excel里面的内容
    @Override
    public void invoke(UserData userData, AnalysisContext analysisContext) {
        System.out.println(userData);
    }
    //读取第一行内容
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        System.out.println("表头信息:"+headMap);
    }
    //读取之后执行
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        System.out.println("读取完毕");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class TestRead {
    public static void main(String[] args) {
        //读取文件路径
        String fileName = "F:\\excel\\01.xlsx";
        //调用方法实现读取操作
        EasyExcel.read(fileName,UserData.class,new ExcelListener()).sheet().doRead();
    }
}
1
2
3
4
5
6
7
8
  • 控制台输出
表头信息:{0=用户编号, 1=用户名称}
UserData(uid=0, username=Lucy0)
UserData(uid=1, username=Lucy1)
UserData(uid=2, username=Lucy2)
UserData(uid=3, username=Lucy3)
UserData(uid=4, username=Lucy4)
UserData(uid=5, username=Lucy5)
UserData(uid=6, username=Lucy6)
UserData(uid=7, username=Lucy7)
UserData(uid=8, username=Lucy8)
UserData(uid=9, username=Lucy9)
读取完毕
Process finished with exit code 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 数据字典导出

# 导出接口封装

# 在 model 模块添加导出实体

@Data
public class DictEeVo {
	@ExcelProperty(value = "id" ,index = 0)
	private Long id;
	@ExcelProperty(value = "上级id" ,index = 1)
	private Long parentId;
	@ExcelProperty(value = "名称" ,index = 2)
	private String name;
	@ExcelProperty(value = "值" ,index = 3)
	private String value;
	@ExcelProperty(value = "编码" ,index = 4)
	private String dictCode;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 在service-cmn模块添加service方法

  1. 在DictService类添加接口
    void exportDictData(HttpServletResponse response);
1
  1. 在DictServiceImpl类添加接口实现类
    //导出数据字典接口
    @Override
    public void exportDictData(HttpServletResponse response) {
        //设置下载信息
        response.setContentType("application/vnd.me-excel");
        response.setCharacterEncoding("utf-8");
        //这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = "dict";
        response.setHeader("Content-disposition","attachment;filename="+fileName+".xlsx");
        //查询数据库
        List<Dict> dictList = baseMapper.selectList(null);
        //Dict --> DictEeVo
        List<DictEeVo> dictEeVoList = new ArrayList<>();
        for (DictEeVo dict: dictEeVoList) {
            DictEeVo dictEeVo = new DictEeVo();
            dictEeVo.setId(dict.getId());
            BeanUtils.copyProperties(dict,dictEeVo,DictEeVo.class);
            dictEeVoList.add(dictEeVo);
        }
        //调用方法
        try {
            EasyExcel.write(response.getOutputStream(), DictEeVo.class).sheet("dict")
                    .doWrite(dictEeVoList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 在service-cmn模块添加controller方法

    //导出数据字典接口
    @GetMapping("/exportData")
    public void exportDict(HttpServletResponse response){
        dictService.exportDictData(response);
    }
1
2
3
4
5

# 测试

直接通过浏览器导出数据:

# 数据字典导入

# 导入接口封装

# 创建回调监听器

public class DictListener extends AnalysisEventListener<DictEeVo> {
    private DictMapper dictMapper;
    public DictListener(DictMapper dictMapper) {
        this.dictMapper = dictMapper;
    }
    //从第二行,一行一行读取
    @Override
    public void invoke(DictEeVo dictEeVo, AnalysisContext analysisContext) {
        //调用方法添加数据
        Dict dict = new Dict();
        BeanUtils.copyProperties(dictEeVo,dict);
        dictMapper.insert(dict);
    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 在service-cmn模块添加service方法

    @Override
    public void importDictData(MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream(),DictEeVo.class,new DictListener(baseMapper))
                    .sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
1
2
3
4
5
6
7
8
9

# 在service-cmn模块添加controller方法

    //导入数据字典
    @PostMapping("/importData")
    public Result importDict(MultipartFile file){
        dictService.importDictData(file);
        return Result.ok();
    }
1
2
3
4
5
6
  • 测试

image

  • 上传后,查询数据库

image

# Spring Cache + Redis 缓存数据

Spring Cache 是一个非常优秀的缓存组件。自Spring 3.1起,提供了类似于@Transactional注解事务的注解Cache支持,且提供了Cache抽象,方便切换各种底层Cache(如:redis)

使用Spring Cache的好处:

  1. 提供基本的Cache抽象,方便切换各种底层Cache;
  2. 通过注解Cache可以实现类似于事务一样,缓存逻辑透明的应用到我们的业务代码上,且只需要更少的代码就可以完成;
  3. 提供事务回滚时也自动回滚缓存;
  4. 支持比较复杂的缓存逻辑;

# 项目集成Spring Cache + Redis

因为缓存也是公共使用,所有的service模块都有可能使用缓存,所以我们把依赖与部分配置加在service-util模块,这样其他service模块都可以使用了。

# service-util添加依赖

在service-util模块的pom.xml添加依赖

<!-- redis -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- spring2.X集成redis所需common-pool2-->
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-pool2</artifactId>
	<version>2.6.0</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12

# service-util添加配置类

@Configuration
@EnableCaching
public class RedisConfig {
    /**
     * 自定义key规则
     *
     * @return
     */
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }
    /**
     * 设置RedisTemplate规则
     *
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = 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);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        //序列号key value
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    /**
     * 设置CacheManager缓存规则
     *
     * @param factory
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

说明:

@EnableCaching:标记注解 @EnableCaching,开启缓存,并配置Redis缓存管理器。@EnableCaching (opens new window) 注释触发后置处理器, 检查每一个Spring bean 的 public 方法是否存在缓存注解。如果找到这样的一个注释, 自动创建一个代理拦截方法调用和处理相应的缓存行为。

# service-cmn添加redis配置

spring.redis.host=192.168.91.166
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0
1
2
3
4
5
6
7
8
9
10

# 使用Spring Cache

# 常用缓存标签

# 缓存 @Cacheable

根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。

查看源码,属性值如下:

属性/方法名 解释
value 缓存名,必填,它指定了你的缓存存放在哪块命名空间
cacheNames 与 value 差不多,二选一即可
key 可选属性,可以使用 SpEL 标签自定义缓存的key

# 缓存 @CachePut

使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上。

查看源码,属性值如下:

属性/方法名 解释
value 缓存名,必填,它指定了你的缓存存放在哪块命名空间
cacheNames 与 value 差不多,二选一即可
key 可选属性,可以使用 SpEL 标签自定义缓存的key

# 缓存 @CacheEvict

使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上

查看源码,属性值如下:

属性/方法名 解释
value 缓存名,必填,它指定了你的缓存存放在哪块命名空间
cacheNames 与 value 差不多,二选一即可
key 可选属性,可以使用 SpEL 标签自定义缓存的key
allEntries 是否清空所有缓存,默认为 false。如果指定为 true,则方法调用后将立即清空所有的缓存
beforeInvocation 是否在方法执行前就清空,默认为false。如果指定为true,则在方法执行前就会清空缓存

# 数据字典应用

改造com.frx01.yygh.cmn.service.impl.DictServiceImpl类方法

 















 










    @Cacheable(value = "dict",keyGenerator = "keyGenerator")
    @Override
    public List<Dict> findChildData(Long id) {
        QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id",id);
        List<Dict> list = baseMapper.selectList(queryWrapper);
        //向list集合中每个dict对象中设置hasChildren
        for (Dict dict : list) {
            Long dictId = dict.getId();
            boolean isChild = this.isChildren(dictId);
            dict.setHasChildren(isChild);
        }
        return list;
    }
    @CacheEvict(value = "dict", allEntries=true)
    @Override
    public void importDictData(MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream(),DictEeVo.class,new DictListener(baseMapper))
                    .sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  • 查看redis
127.0.0.1:6379> keys *
1) "dict::com.frx01.yygh.service.impl.DictServiceImplfindChildData1"
127.0.0.1:6379> get dict::com.frx01.yygh.service.impl.DictServiceImplfindChildData1
"[\"java.util.ArrayList\",[[\"com.frx01.yygh.model.cmn.Dict\",{\"id\":86,\"createTime\":[\"java.util.Date\",\"2019-06-10 02:43:35\"],\"updateTime\":[\"java.util.Date\",1592898228000],\"isDeleted\":0,\"param\":[\"java.util.HashMap\",{}],\"parentId\":1,\"name\":\"\xe7\x9c\x81\",\"value\":\"86\",\"dictCode\":\"Province\",\"hasChildren\":true}],[\"com.frx01.yygh.model.cmn.Dict\",{\"id\":10000,\"createTime\":[\"java.util.Date\",\"2019-06-10 02:43:32\"],\"updateTime\":[\"java.util.Date\",1592191604000],\"isDeleted\":0,\"param\":[\"java.util.HashMap\",{}],\"parentId\":1,\"name\":\"\xe5\x8c\xbb\xe9\x99\xa2\xe7\xad\x89\xe7\xba\xa7\",\"value\":null,\"dictCode\":\"Hostype\",\"hasChildren\":true}],[\"com.frx01.yygh.model.cmn.Dict\",{\"id\":20000,\"createTime\":[\"java.util.Date\",\"2019-06-10 02:43:32\"],\"updateTime\":[\"java.util.Date\",1592290377000],\"isDeleted\":0,\"param\":[\"java.util.HashMap\",{}],\"parentId\":1,\"name\":\"\xe8\xaf\x81\xe4\xbb\xb6\xe7\xb1\xbb\xe5\x9e\x8b\",\"value\":\"20000\",\"dictCode\":\"CertificatesType\",\"hasChildren\":true}],[\"com.frx01.yygh.model.cmn.Dict\",{\"id\":30000,\"createTime\":[\"java.util.Date\",\"2019-06-10 02:43:32\"],\"updateTime\":[\"java.util.Date\",1591608399000],\"isDeleted\":0,\"param\":[\"java.util.HashMap\",{}],\"parentId\":1,\"name\":\"\xe5\xad\xa6\xe5\x8e\x86\",\"value\":\"30000\",\"dictCode\":\"Education\",\"hasChildren\":true}],[\"com.frx01.yygh.model.cmn.Dict\",{\"id\":99100,\"createTime\":[\"java.util.Date\",\"2019-06-11 02:39:11\"],\"updateTime\":[\"java.util.Date\",1591608399000],\"isDeleted\":0,\"param\":[\"java.util.HashMap\",{}],\"parentId\":1,\"name\":\"\xe6\xb0\x91\xe6\x97\x8f\",\"value\":\"99100\",\"dictCode\":\"Nation\",\"hasChildren\":true}]]]"
1
2
3
4

# 配置Nginx

由于我们后端有很多服务模块,每个模块都有对应的访问路径与端口,为了提供统一的api接口,所以使用nginx作为反向代理服务器;

反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址

  1. 下载安装Nginx(Windows版)
  2. 配置nginx
server {
        listen       9001;
        server_name  localhost;
	location ~ /hosp/ {           
	    proxy_pass http://localhost:8201;
	}
	location ~ /cmn/ {           
	    proxy_pass http://localhost:8202;
	}
}
1
2
3
4
5
6
7
8
9
10
11

1,调整/config/dev.env.js中的BASE_API

BASE_API: 'http://localhost:9001'

说明:

1、后续我们会使用Spring Cloud Gateway网关,将替代nginx网关

帮助我改善此页面 (opens new window)
#中高进阶篇
上次更新: 2024年3月20日
尚医通-前端知识点
尚医通-MongoDB

← 尚医通-前端知识点 尚医通-MongoDB→

最近更新
01
结构型模式
03-21
02
创建者模式
01-20
03
设计模式入门
12-30
更多文章>
Theme by Vdoing | Copyright © 2021-2024 xustudyxu |豫ICP备2022008983号

豫公网安备 41018302000331号

  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式