service_cmn
数据字典
何为数据字典?数据字典就是管理系统常用的分类数据,或者一些固定数据,例如:省市区三级联动数据、民族数据、行业数据、学历数据等,由于该系统大量使用这种数据,所以我们要做一个数据管理方便管理系统数据,一般系统基本都会做数据管理。
数据库MySql
查询方式
数据字典是树形展示,由于数据众多,我们使用“树形数据与懒加载”的方式展现数据列表。
懒加载:
由于组织单元间存在着上下级关系,那么组织单元的排列就可以当作一棵树来处理。在显示数据时只显示父节点,点击父节点时,就能显示父节点下的子节点。懒加载节省了系统响应时间,提升了系统性能,非常具有利用价值。
根据Element-ui的要求,当 row 中包含 children 字段时,被视为树形数据。所以实体类需要加上hasChildren属性,但是这个属性表里没有,所以要加注解@TableField(exist = false)
@ApiModelProperty(value = "是否包含子节点")
@TableField(exist = false)//false表示这个字段在表里可以不存在
private boolean hasChildren;
model
Dict
controller
查(根据id查询,子数据的parent_id等于传入的参数id
//根据数据id查询子数据列表
@ApiOperation(value = "根据数据id查询子数据列表")
@GetMapping("findChildData/{id}")
public Result findChildData(@PathVariable Long id) {
List<Dict> list = dictService.findChlidData(id);
return Result.ok(list);
}
service
//根据数据id查询子数据列表
@Override
public List<Dict> findChlidData(Long id) {
QueryWrapper<Dict> wrapper = new QueryWrapper<>();
wrapper.eq("parent_id",id);
List<Dict> dictList = baseMapper.selectList(wrapper);
//向list集合每个dict对象中设置hasChildren
for (Dict dict:dictList) {
Long dictId = dict.getId();
boolean isChild = this.isChildren(dictId);
dict.setHasChildren(isChild);
}
return dictList;
}
//判断id下面是否有子节点
private boolean isChildren(Long id) {
QueryWrapper<Dict> wrapper = new QueryWrapper<>();
wrapper.eq("parent_id",id);
Integer count = baseMapper.selectCount(wrapper);
// 0>0 1>0
return count>0;
}
前端
后端就一个根据id查询的方法,前端页面一渲染时用的是created() {this.getDictList(1)}方法,意思是一开始查的是id=1的,也就是”全部分类“,再判断下面有没有子节点,根据parent_id=id查下面的。
EasyExcel
EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。
在model模块添加导出实体
导出
//设置下载信息
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = "dict";
response.setHeader("Content-disposition", "attachment;filename=" +
fileName + ".xlsx");
//先把所有数据查询出来
List<Dict> dictList = baseMapper.selectList(null);
//把查询出的Dict对象转换成DictEeVo对象
ArrayList<DictEeVo> dictEeVos = new ArrayList<>(dictList.size());
for(Dict dict : dictList){
DictEeVo dictEeVo = new DictEeVo();
BeanUtils.copyProperties(dict, dictEeVo, DictEeVo.class);
dictEeVos.add(dictEeVo);
}
//调用方法进行写操作
try {
EasyExcel.write(response.getOutputStream(), DictEeVo.class).sheet("数据字典")
.doWrite(dictEeVos);
} catch (IOException e) {
e.printStackTrace();
}
导入
public void importDictData(MultipartFile file) {
try {
EasyExcel.read(file.getInputStream(),DictEeVo.class,
new DictListener(baseMapper)).sheet().doRead();
} catch (IOException e) {
e.printStackTrace();
}
}
缓存
项目集成Spring Cache + Redis
Spring Cache 是一个非常优秀的缓存组件。(TODO)
使用Spring Cache
因为缓存也是公共使用,所有的service模块都有可能使用缓存,所以我们把依赖与部分配置加在service-util模块,这样其他service模块都可以使用了。
配置类:RedisConfig
Spring Cache常用缓存标签
@Cacheable:
根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。
@CachePut:
使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上。
@CacheEvict:
使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上
数据字典应用
在servie方法上加注解
(查询方法加@Cacheable)
//缓存,将返回的list集合放到缓存中,第二次查直接从缓存中查
//属性值表示生成的key的名字
@Cacheable(value = "dict",keyGenerator = "keyGenerator")
@Override
public List<Dict> findByParentId(Long parentId) {
}
(导入方法加@CacheEvict)
//表示清空缓存,因为是添加操作,清空后重新往里添加,清空"dict"规则下的缓存
@CacheEvict(value = "dict", allEntries=true)
@Override
public void importData(MultipartFile file) {
}