1. 数据字典介绍

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

1.1 页面效果

image.png

1.2 表设计

image.png

1.3 数据分析

image.png
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

1.4 根据页面效果分析数据接口

数据字典是树形展示,由于数据众多,我们使用“树形数据与懒加载”的方式展现数据列表,其他就是对数据的新增、修改与删除操作,因此需要提供的接口如下:
1,根据上级id获取下级数据(构造树形数据),参考文档:https://element.eleme.cn/#/zh-CN/component/table,页面搜索:树形数据与懒加载
2,导入接口
3,导出接口
接下来我们封装服务器端数据接口,接口测试通过后再做页面渲染

2. 数据字典开发

2.1 搭建service-cmn模板

2.1.1 搭建service-cmn模板

搭建过程参考service-hosp模块

2.1.2 修改配置

修改pom.xml

  1. <?xml version="1.0"encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>com.atguigu.yygh</groupId>
  7. <artifactId>service</artifactId>
  8. <version>1.0</version>
  9. </parent>
  10. <version>1.0</version>
  11. <artifactId>service-cmn</artifactId>
  12. <packaging>jar</packaging>
  13. <name>service-cmn</name>
  14. <description>service-cmn</description>
  15. <dependencies>
  16. </dependencies>
  17. <build>
  18. <finalName>service-cmn</finalName>
  19. <plugins>
  20. <plugin>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-maven-plugin</artifactId>
  23. </plugin>
  24. </plugins>
  25. </build>
  26. </project>

1、添加配置文件application.properties

  1. # 服务端口
  2. server.port=8202
  3. # 服务名
  4. spring.application.name=service-cmn
  5. # 环境设置:devtestprod
  6. spring.profiles.active=dev
  7. # mysql数据库连接
  8. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  9. spring.datasource.url=jdbc:mysql://192.168.44.165:3306/yygh_cmn?characterEncoding=utf-8&useSSL=false
  10. spring.datasource.username=root
  11. spring.datasource.password=root123
  12. #返回json的全局时间格式
  13. spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
  14. spring.jackson.time-zone=GMT+8

2.1.3 启动类

  1. package com.atguigu.yygh;
  2. @SpringBootApplication
  3. public class ServiceCmnApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(ServiceCmnApplication.class, args);
  6. }
  7. }

2.2 数据字典列表

根据element组件要求,返回列表数据必须包含hasChildren字典,如图:
https://element.eleme.cn/#/zh-CN/component/table
image.png

2.2.1 数据字典列表接口

2.2.1.1 model模板添加数据字典实体

在model模块查看实体:com.atguigu.yygh.model.cmn.Dict

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

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

2.2.1.2 添加数据字典mapper

添加com.atguigu.yygh.cmn.mapper.DictMapper

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

2.2.1.3 添加数据字典service

1、添加com.atguigu.yygh.cmn.service.DictService

  1. public interface DictService extends IService<Dict> {
  2. //根据数据id查询子数据列表
  3. List<Dict> findChlidData(Long id);
  4. }

2、添加com.atguigu.yygh.cmn.service.impl.DictServiceImpl接口实现

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

2.2.1.4 添加数据字典controller

添加com.atguigu.yygh.cmn.controller.DictController

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

2.2.2 数据字典列表前端

2.2.2.1 添加路由

在 src/router/index.js 文件添加路由

  1. {
  2. path: '/cmn',
  3. component: Layout,
  4. redirect: '/cmn/list',
  5. name: '数据管理',
  6. alwaysShow: true,
  7. meta: { title: '数据管理', icon: 'example' },
  8. children: [
  9. {
  10. path: 'list',
  11. name: '数据字典',
  12. component: () => import('@/views/dict/list'),
  13. meta: { title: '数据字典', icon: 'table' }
  14. }
  15. ]
  16. },

说明:列表与查看都添加了

2.2.2.2 定义api

创建文件 src/api/cmn/dict.js

  1. export default {
  2. dictList(id) {//数据字典列表
  3. return request ({
  4. url: `/admin/cmn/dict/findChildData/${id}`,
  5. method: 'get'
  6. })
  7. }
  8. }

2.2.2.3 方法调用

  1. <script>
  2. import dict from '@/api/dict'
  3. export default {
  4. data() {
  5. return {
  6. list:[] //数据字典列表数组
  7. }
  8. },
  9. created() {
  10. this.getDictList(1)
  11. },
  12. methods: {
  13. //数据字典列表
  14. getDictList(id) {
  15. dict.dictList(id)
  16. .then(response => {
  17. this.list = response.data
  18. })
  19. },
  20. getChildrens(tree, treeNode, resolve) {
  21. dict.dictList(tree.id).then(response => {
  22. resolve(response.data)
  23. })
  24. }
  25. }
  26. }
  27. </script>

2.2.2.4 表格渲染

  1. <template>
  2. <div class="app-container">
  3. <el-table
  4. :data="list"
  5. style="width: 100%"
  6. row-key="id"
  7. border
  8. lazy
  9. :load="getChildrens"
  10. :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
  11. <el-table-column label="名称" width="230" align="left">
  12. <template slot-scope="scope">
  13. <span>{{ scope.row.name }}</span>
  14. </template>
  15. </el-table-column>
  16. <el-table-column label="编码" width="220">
  17. <template slot-scope="{row}">
  18. {{ row.dictCode }}
  19. </template>
  20. </el-table-column>
  21. <el-table-column label="值" width="230" align="left">
  22. <template slot-scope="scope">
  23. <span>{{ scope.row.value }}</span>
  24. </template>
  25. </el-table-column>
  26. <el-table-column label="创建时间" align="center">
  27. <template slot-scope="scope">
  28. <span>{{ scope.row.createTime }}</span>
  29. </template>
  30. </el-table-column>
  31. </el-table>
  32. </div>
  33. </template>

2.3 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
github地址:https://github.com/alibaba/easyexcel

2.3.1 导出示例

示例链接:https://alibaba-easyexcel.github.io/quickstart/write.html

2.3.2 导入示例

示例链接:https://alibaba-easyexcel.github.io/quickstart/read.html

2.3.3 EasyExcel集成

2.3.3.1 添加依赖

  1. 添加依赖

    1. <dependencies>
    2. <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
    3. <dependency>
    4. <groupId>com.alibaba</groupId>
    5. <artifactId>easyexcel</artifactId>
    6. <version>2.1.1</version>
    7. </dependency>
    8. </dependencies>

    说明:我们已经在yygh-parent中的pom.xml中添加了所有依赖管理

  2. 导入导出需要定义对象,对象上需要引用easyexcel标签,所以model模块需要引入,scope:provided ```java

    com.alibaba easyexcel provided
  1. 3. 导入导出我们会把它封装成工具类,放在common-util中,所有模块公用,所以该模块也得引入
  2. ```java
  3. <dependency>
  4. <groupId>com.alibaba</groupId>
  5. <artifactId>easyexcel</artifactId>
  6. </dependency>

2.4 数据字典导出

2.4.1 导出接口封装

2.4.1.1 在model模块添加导出实体

在model模块查看实体:com.atguigu.yygh.vo.cmn.DictEeVo

  1. package com.atguigu.yygh.vo.cmn;
  2. @Data
  3. public class DictEeVo {
  4. @ExcelProperty(value = "id",index = 0)
  5. private Long id;
  6. @ExcelProperty(value = "上级id",index = 1)
  7. private Long parentId;
  8. @ExcelProperty(value = "名称",index = 2)
  9. private String name;
  10. @ExcelProperty(value = "值",index = 3)
  11. private String value;
  12. @ExcelProperty(value = "编码",index = 4)
  13. private String dictCode;
  14. }

2.4.1.2 在service-cmn模板添加service方法

1、在DictService类添加接口

  1. /**
  2. * 导出
  3. * @param response
  4. */
  5. void exportData(HttpServletResponse response);

2、在DictServiceImpl类添加接口实现类

  1. @Override
  2. public void exportData(HttpServletResponse response) {
  3. try {
  4. response.setContentType("application/vnd.ms-excel");
  5. response.setCharacterEncoding("utf-8");
  6. // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
  7. String fileName = URLEncoder.encode("数据字典", "UTF-8");
  8. response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");
  9. List<Dict> dictList = dictMapper.selectList(null);
  10. List<DictEeVo> dictVoList = new ArrayList<>(dictList.size());
  11. for(Dict dict : dictList) {
  12. DictEeVo dictVo = new DictEeVo();
  13. BeanUtils.copyBean(dict, dictVo, DictEeVo.class);
  14. dictVoList.add(dictVo);
  15. }
  16. EasyExcel.write(response.getOutputStream(), DictEeVo.class).sheet("数据字典").doWrite(dictVoList);
  17. } catch (IOException e) {
  18. e.printStackTrace();
  19. }
  20. }

说明:直接复制示例代码中的“web中的写”,改造即可

2.4.1.3 在service-cmn木块添加controller方法

在DictController类添加方法

  1. @ApiOperation(value="导出")
  2. @GetMapping(value = "/exportData")
  3. public void exportData(HttpServletResponse response) {
  4. dictService.exportData(response);
  5. }

2.4.1.4 测试

直接通过浏览器导出数据:http://localhost:8202/admin/cmn/dict/exportData

2.4.2 导出前端实现

2.4.2.1 列表页面添加导出按钮

src/views/cmn/dict/list.vue

  1. <div class="el-toolbar">
  2. <div class="el-toolbar-body"style="justify-content: flex-start;">
  3. <el-button type="text"@click="exportData"><i class="fa fa-plus"/> 导出</el-button>
  4. </div>
  5. </div>

2.4.2.2 添加导出方法

  1. exportData() {
  2. window.location.href = 'http://localhost:8202/admin/cmn/dict/exportData'
  3. }

2.4.2.3 测试

2.5 数据字典导入

2.5.1 导入接口封装

2.5.1.1 创建回调监听器

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

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

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

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

在DictController类添加方法

  1. @ApiOperation(value = "导入")
  2. @PostMapping("importData")
  3. public Result importData(MultipartFile file) {
  4. dictService.importData(file);
  5. return Result.ok();
  6. }

2.5.2 导入前端实现

2.5.2.1 列表页面添加导入按钮

src/views/cmn/dict/list.vue

  1. <el-button type="text"@click="importData"><i class="fa fa-plus"/> 导入</el-button>

说明:按钮位置与导出并列

2.5.2.2 添加导入弹出层

  1. <el-dialog title="导入":visible.sync="dialogImportVisible"width="480px">
  2. <el-form label-position="right"label-width="170px">
  3. <el-form-item label="文件">
  4. <el-upload
  5. :multiple="false"
  6. :on-success="onUploadSuccess"
  7. :action="'http://localhost:8202/admin/cmn/dict/importData'"
  8. class="upload-demo">
  9. <el-button size="small"type="primary">点击上传</el-button>
  10. <div slot="tip"class="el-upload__tip">只能上传xls文件,且不超过500kb</div>
  11. </el-upload>
  12. </el-form-item>
  13. </el-form>
  14. <div slot="footer"class="dialog-footer">
  15. <el-button @click="dialogImportVisible = false">
  16. 取消
  17. </el-button>
  18. </div>
  19. </el-dialog>

2.5.2.3 添加弹出可见模型

  1. // 定义数据
  2. data() {
  3. return {
  4. list: [],
  5. listLoading: true,
  6. dialogImportVisible: false
  7. }
  8. }

2.5.2.4 添加方法

  1. importData() {
  2. this.dialogImportVisible = true
  3. },
  4. onUploadSuccess(response, file) {
  5. this.$message.info('上传成功')
  6. this.dialogImportVisible = false
  7. this.fetchData()
  8. }

3. Spring Cache +Redis缓存数据

Spring Cache 是一个非常优秀的缓存组件。自Spring 3.1起,提供了类似于@Transactional注解事务的注解Cache支持,且提供了Cache抽象,方便切换各种底层Cache(如:redis)
使用Spring Cache的好处:
1,提供基本的Cache抽象,方便切换各种底层Cache;
2,通过注解Cache可以实现类似于事务一样,缓存逻辑透明的应用到我们的业务代码上,且只需要更少的代码就可以完成;
3,提供事务回滚时也自动回滚缓存;
4,支持比较复杂的缓存逻辑;

3.1 项目集成Spring Cache +Redis

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

3.1.1 service-util添加依赖

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

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

3.1.2 service-util添加配置类

创建com.atguigu.yygh.common.config.RedisConfig

  1. package com.atguigu.yygh.common.config;
  2. @Configuration
  3. @EnableCaching
  4. public class RedisConfig {
  5. /**
  6. * 自定义key规则
  7. * @return
  8. */
  9. @Bean
  10. public KeyGenerator keyGenerator() {
  11. return new KeyGenerator() {
  12. @Override
  13. public Object generate(Object target, Method method, Object... params) {
  14. StringBuilder sb = new StringBuilder();
  15. sb.append(target.getClass().getName());
  16. sb.append(method.getName());
  17. for (Object obj : params) {
  18. sb.append(obj.toString());
  19. }
  20. return sb.toString();
  21. }
  22. };
  23. }
  24. /**
  25. * 设置RedisTemplate规则
  26. * @param redisConnectionFactory
  27. * @return
  28. */
  29. @Bean
  30. public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
  31. RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
  32. redisTemplate.setConnectionFactory(redisConnectionFactory);
  33. Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
  34. //解决查询缓存转换异常的问题
  35. ObjectMapper om = new ObjectMapper();
  36. // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
  37. om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  38. // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
  39. om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
  40. jackson2JsonRedisSerializer.setObjectMapper(om);
  41. //序列号key value
  42. redisTemplate.setKeySerializer(new StringRedisSerializer());
  43. redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
  44. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
  45. redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
  46. redisTemplate.afterPropertiesSet();
  47. return redisTemplate;
  48. }
  49. /**
  50. * 设置CacheManager缓存规则
  51. * @param factory
  52. * @return
  53. */
  54. @Bean
  55. public CacheManager cacheManager(RedisConnectionFactory factory) {
  56. RedisSerializer<String> redisSerializer = new StringRedisSerializer();
  57. Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
  58. //解决查询缓存转换异常的问题
  59. ObjectMapper om = new ObjectMapper();
  60. om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  61. om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
  62. jackson2JsonRedisSerializer.setObjectMapper(om);
  63. // 配置序列化(解决乱码的问题),过期时间600秒
  64. RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
  65. .entryTtl(Duration.ofSeconds(600))
  66. .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
  67. .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
  68. .disableCachingNullValues();
  69. RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
  70. .cacheDefaults(config)
  71. .build();
  72. return cacheManager;
  73. }
  74. }

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

3.1.3 service-util添加redis配置

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

3.2 使用Spring Cache

3.2.1 常用缓存标签

3.2.1.1 缓存@Cacheable

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

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

3.2.1.2 缓存@CachePut

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

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

3.2.1.3 缓存@CacheEvict

使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上
查看源码,属性值如下:

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

3.2.2 数据字典应用

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

  1. /**
  2. * 根据上级id获取子节点数据列表
  3. * @param parentId
  4. */
  5. @Cacheable(value = "dict",keyGenerator = "keyGenerator")
  6. @Override
  7. public List<Dict> findByParentId(Long parentId) {
  8. List<Dict> dictList = dictMapper.selectList(new QueryWrapper<Dict>().eq("parent_id", parentId));
  9. dictList.stream().forEach(dict -> {
  10. boolean isHasChildren = this.isHasChildren(dict.getId());
  11. dict.setHasChildren(isHasChildren);
  12. });
  13. return dictList;
  14. }
  15. /**
  16. * 导入
  17. * allEntries = true: 方法调用后清空所有缓存
  18. * @param file
  19. */
  20. @CacheEvict(value = "dict", allEntries=true)
  21. @Override
  22. public void importData(MultipartFile file) {
  23. ExcelHelper fileHelper = new ExcelHelper(DictEeVo.class);
  24. List<DictEeVo> dictVoList = fileHelper.importExcel(file);
  25. if(!CollectionUtils.isEmpty(dictVoList)) {
  26. dictMapper.insertBatch(dictVoList);
  27. }
  28. }