尚医通06:数据字典+EasyExcel+mongodb

内容介绍

1、数据字典列表前端

2、EasyExcel介绍、实例

3、数据字典导出接口、前端

4、数据字典导入接口、前端

5、数据字典添加redis缓存

6、MongoDB简介

7、MongoDB安装

8、MongoDB基本概念

数据字典列表前端

1、测试问题

1)报错日志

2)问题定位

URL错误

3)解决问题

2nginx

1)基本功能

反向代理、负载均衡、动静分离

2)安装

解压即可使用

3)启动

4)修改配置

server {

    listen 9001;

    server_name localhost;

    location ~/hosp/ {          

        proxy_pass http://localhost:8201;

    }

    location ~/cmn/ {          

        proxy_pass http://localhost:8202;

    }

}

重启服务或重新加载(nginx.exe -s reload)才可生效

5)测试访问后端接口

http://localhost:9001/admin/hosp/hospitalSet/findAll

6)改造前端

重启生效

EasyExcel介绍、实例

1、是什么

EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。

2、为什么

没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

3、准备工作

1cmn导入依赖

<dependencies>

    <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->

    <dependency>

        <groupId>com.alibaba</groupId>

        <artifactId>easyexcel</artifactId>

        <version>2.1.1</version>

    </dependency>

  </dependencies>

2)创建目录、创建实体

@Data

  public class Stu {

    //设置表头名称

    @ExcelProperty("学生编号")

    private int sno;

    //设置表头名称

    @ExcelProperty("学生姓名")

    private String sname;

  }

4、实现写操作

public class WriterTest {

    public static void main(String[] args) {

        String fileName = "D:\\test\\230308\\a.xlsx";

        EasyExcel.write(fileName,Stu.class)

                .sheet("学员信息").doWrite(data());

    }

  

    //循环设置要添加的数据,最终封装到list集合中

    private static List<Stu> data() {

        List<Stu> list = new ArrayList<Stu>();

        for (int i = 0; i < 10; i++) {

            Stu data = new Stu();

            data.setSno(i);

            data.setSname("张三"+i);

            list.add(data);

        }

        return list;

    }

  }

5、实现读操作

1)改造实体

@Data

  public class Stu {

    //设置表头名称

    @ExcelProperty(value = "学生编号",index = 0)

    private int sno;

    //设置表头名称

    @ExcelProperty(value = "学生姓名",index = 1)

    private String sname;

  }

2)创建监听器

public class ExcelListener extends AnalysisEventListener<Stu> {

    @Override

    public void invoke(Stu stu, AnalysisContext analysisContext) {

        //可以实现调用接口,数据入库

        System.out.println("stu = " + stu);

    }

  

    //读取excel表头信息

    @Override

    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {

        System.out.println("表头信息:"+headMap);

    }

  

    @Override

    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

  

    }

  }

3)读数据实例

public class ReadTest {

    public static void main(String[] args) {

        String fileName = "D:\\test\\230308\\a.xlsx";

        EasyExcel.read(fileName,Stu.class,new ExcelListener()).sheet().doRead();

    }

  }

数据字典导出、前端

1、准备工作

1)确认依赖

2)确认对象

2、实现导出接口

1)分析接口

*参数:response

*返回值:无

2)实现controller

@ApiOperation(value="导出")

  @GetMapping(value = "/exportData")

  public void exportData(HttpServletResponse response) {

    dictService.exportData(response);

  }

3)实现service

//导出

  @Override

  public void exportData(HttpServletResponse response) {

    try {

        //1设置response参数

        response.setContentType("application/vnd.ms-excel");

        response.setCharacterEncoding("utf-8");

        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系

        String fileName = URLEncoder.encode("数据字典", "UTF-8");

        response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");

        //2查询数据字典表数据List<Dict>

        List<Dict> dictList = baseMapper.selectList(null);

        //3遍历集合List<Dict>转型List<DictEeVo>

        List<DictEeVo> dictEeVoList = new ArrayList<>();

        for (Dict dict : dictList) {

            DictEeVo dictEeVo = new DictEeVo();

            BeanUtils.copyProperties(dict,dictEeVo);

            dictEeVoList.add(dictEeVo);

        }

        //4调用工具方法导出数据

        ServletOutputStream outputStream = response.getOutputStream();

        EasyExcel.write(outputStream,DictEeVo.class)

                .sheet("数据字典").doWrite(dictEeVoList);

  

    } catch (IOException e) {

        throw new YyghException(20001,"导出失败");

    }

  

  }

3、对接前端

1)添加页面元素

<div class="el-toolbar">

      <div class="el-toolbar-body" style="justify-content: flex-start;">

        <el-button type="text" @click="exportData">

          <i class="fa fa-plus"/> 导出

        </el-button>

      </div>

    </div>

(2)实现js方法

//导出数据

    exportData(){

        window.open(`${process.env.VUE_APP_BASE_API}admin/cmn/dict/exportData`)

    }

3)测试

数据字典导入、前端

1数据字典导入接口

1)分析接口

*参数:file

*返回值:R.ok()

2)实现controller

@ApiOperation(value = "导入")

  @PostMapping("importData")

  public R importData(MultipartFile file) {

    dictService.importData(file);

    return R.ok();

  }

3)创建监听器

@Component

  public class DictListener  extends AnalysisEventListener<DictEeVo> {

    

    @Autowired

    private DictMapper dictMapper;

    

    //手动注入,使用有参构造

    //private DictMapper dictMapper;

    

    @Override

    public void invoke(DictEeVo dictEeVo, AnalysisContext analysisContext) {

        //1转化数据类型DictEeVo=Dict

        Dict dict = new Dict();

        BeanUtils.copyProperties(dictEeVo,dict);

        //2补充数据

        dict.setIsDeleted(0);

        //3数据入库

        dictMapper.insert(dict);

    }

  

    @Override

    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

  

    }

  }

4实现service

@Autowired

  private DictListener dictListener;

//导入

  @Override

  public void importData(MultipartFile file) {

    try {

        InputStream inputStream = file.getInputStream();

        EasyExcel.read(inputStream,DictEeVo.class,dictListener).sheet().doRead();

    } catch (IOException e) {

        throw new YyghException(20001,"导入失败");

    }

  }

5)测试

2、对接前端

1)分析需求

2)查看组件

3)添加页面元素

<div class="el-toolbar">

      <div class="el-toolbar-body" style="justify-content: flex-start;">

        <el-button type="text" @click="exportData">

          <i class="fa fa-plus"/> 导出

        </el-button>

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

      </div>

    </div>

<el-dialog title="导入" :visible.sync="dialogImportVisible" width="480px">

      <el-form label-position="right" label-width="170px">

        <el-form-item label="文件">

          <el-upload

            :multiple="false"

            :on-success="onUploadSuccess"

            :action="BASE_URL+'admin/cmn/dict/importData'"

            class="upload-demo"

          >

            <el-button size="small" type="primary">点击上传</el-button>

            <div slot="tip" class="el-upload__tip">只能上传xls文件,且不超过500kb</div>

          </el-upload>

        </el-form-item>

      </el-form>

      <div slot="footer" class="dialog-footer">

        <el-button @click="dialogImportVisible = false">取消</el-button>

      </div>

    </el-dialog>

4)实现js

*属性

data() {

    return {

      list: [],

      dialogImportVisible: false, //对话框是否显示

      BASE_URL: process.env.VUE_APP_BASE_API //基础访问地址

    };

  },

……

*方法

//打开导入窗口

    importData() {

      this.dialogImportVisible = true;

    },

    //导入成功方法

    onUploadSuccess(response, file) {

      this.$message.success("上传成功");

      this.dialogImportVisible = false;

      this.getData();

    }

数据字典添加redis缓存

1redis回顾

2、准备工作

1)虚拟机

2)安装redis

3)检查配置

4)启动redis

3redis缓存访问机制

4、整合redis

1common_utils模块,添加redis依赖

<dependencies>

    <!-- 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>

  </dependencies>

2common_utils模块,添加Redis配置类

@Configuration

@EnableCaching

  public class RedisConfig {

    /**

     * 设置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,getset,以及修饰符范围,ANY是都有包括privatepublic

        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;

    }

  

  }

3)在service_cmn模块添加redis配置

spring.redis.host=192.168.140.138

  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
 

(4)查询方法添加注解

@Override

  // redis k:v   k=dict::selectIndexList  v=List<Dict>

  @Cacheable(value = "dict", key = "'selectIndexList'")

  public List<Dict> findChildData(Long id) {

    //1拼写查询条件

    LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();

    wrapper.eq(Dict::getParentId,id);

    //2查询子数据集合

    List<Dict> dictList = baseMapper.selectList(wrapper);

    //3遍历集合,确认是否有子数据

    for (Dict dict : dictList) {

        boolean isChildren = this.isChildren(dict);

        dict.setHasChildren(isChildren);

    }

    return dictList;

  }

5、问题解决

1)问题描述

*一级数据可以走缓存

*二级数据加载不出来

2)问题定位

*二级数据查询需要查询数据库

*二级数据没有查询数据库,查询缓存获取一级数据

3)解决方案

让多次查询redis缓存的key不一样

//根据数据id查询子数据列表

  @Override

  // redis k:v   k=dict::selectIndexList  v=List<Dict>

  @Cacheable(value = "dict", key = "'selectIndexList'+#id")

  public List<Dict> findChildData(Long id) {

    //1拼写查询条件

    LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();

    wrapper.eq(Dict::getParentId,id);

    //2查询子数据集合

    List<Dict> dictList = baseMapper.selectList(wrapper);

    //3遍历集合,确认是否有子数据

    for (Dict dict : dictList) {

        boolean isChildren = this.isChildren(dict);

        dict.setHasChildren(isChildren);

    }

    return dictList;

  }

4redis缓存写操作同步机制

MongoDB简介

1 NoSQL概述

2MongoDB是什么

MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。

MongoDB 是文档型NOSQL数据库

MongoDB安装

1、安装

1)确认docker服务

2)下载

docker pull mongo:latest

docker pull mongo:4.4.8

3)创建和启动容器

docker run -d --restart=always -p 27017:27017 --name mymongo -v /data/db:/data/db -d mongo:4.4.8

(4)进入容器

docker exec -it mymongo /bin/bash

5)进入mongo

mongo

新版本:mongosh

MongoDB概念介绍

1、与mysql对比

2、数据库(文件柜)

1Help查看命令提示

db.help();

2use test

如果数据库不存在,则创建数据库,否则切换到指定数据库

3 查询所有数据库

show dbs;

4)删除当前使用数据库

db.dropDatabase();

5)查看当前使用的数据库

db.getName();

6)显示当前db状态

db.stats();

7)当前db版本

db.version();

8 查看当前db的链接机器地址

db.getMongo();

3、集合(抽屉)

1、 创建一个集合(table)

db.createCollection( "user");

2、 得到指定名称的集合(table )

db.getCollection("user");

4、文档

文档是一组键值(key-value)对(即BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别

1)数据类型

猜你喜欢

转载自blog.csdn.net/leader_song/article/details/131967655