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

news2024/9/23 23:32:23
内容介绍

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)数据类型

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/798661.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEW开发小型减阻试验平台

LabVIEW开发小型减阻试验平台 湍流摩擦在粘性流体的阻力中起着重要作用&#xff0c;减少湍流摩擦是流体力学领域的热门话题之一。在油气管道的长距离流体输送中&#xff0c;泵站提供的几乎所有动力都用于克服流体的胫骨摩擦。在流体输送领域&#xff0c;船舶的蒙皮摩擦阻力占总…

函数详细解析

目录 形参有默认值的函数 基本概述 指令角度 设定形参默认值 内联函数 基本概述 代码段 函数重载 答疑解惑 形参有默认值的函数 基本概述 从右向左设定形参默认值 形参默认值可以在定义时设定&#xff0c;也可以在声明时设定 每个形参的默认值只能被设定一次 指令角度…

华为HCIP第二节-------------------------ISIS

IS-IS&#xff08;Intermediate System to Intermediate System&#xff0c;中间系统到中间系统&#xff09;是ISO &#xff08;International Organization for Standardization&#xff0c;国际标准化组织&#xff09;为它的CLNP&#xff08;ConnectionLessNetwork Protocol&…

1200*B. Vanya and Lanterns

Examples input 7 15 15 5 3 7 9 14 0 output 2.5000000000 input 2 5 2 5 output 2.0000000000 解析&#xff1a; 最大距离即为每相邻两盏灯之间的最大距离/2 注意起点没有灯&#xff0c;终点可能有灯&#xff0c;需要分别判断 #include<bits/stdc.h> using nam…

前端html中让两个或者多个div在一行显示,用style给div加上css样式

文章目录 前言一、怎么让多个div在一行显示 前言 DIV是层叠样式表中的定位技术&#xff0c;全称DIVision&#xff0c;即为划分。有时可以称其为图层。DIV在编程中又叫做整除&#xff0c;即只得商的整数。 DIV元素是用来为HTML&#xff08;标准通用标记语言下的一个应用&#x…

如何在MacBook上彻底删除mysql

好久以前安装过&#xff0c;但是现在配置mysql一直出错&#xff0c;索性全部删掉重新配置。 一、停止MySQL服务 首先&#xff0c;请确保 MySQL 服务器已经停止运行&#xff0c;以免影响后续的删除操作。 sudo /usr/local/mysql/support-files/mysql.server stop如果你输入之…

DAY3,Qt(完成闹钟的实现,定时器事件处理函数的使用)

1.完成闹钟的实现&#xff0c;到点播报文本框的内容&#xff1b; ---alarm.h---头文件 #ifndef ALARM_H #define ALARM_H#include <QWidget> #include <QTimerEvent> //定时器处理函数类 #include <QTime> //时间类 #include <QPushButton> //按钮…

小红书舆情处理方法丨小红书负面笔记处理的三种技巧

小红书作为一个生活分享平台&#xff0c;经常会刷到一些负面笔记。更多用户的浏览&#xff0c;点赞收藏&#xff0c;评论行为会使笔记热度更高&#xff0c;笔记搜索排名靠前&#xff0c;如果品牌对负面舆情处置方法不当很可能影响公司品牌信誉&#xff0c;导致用户流失。 小红书…

WEB:unseping

背景知识 php序列化和反序列化 命令执行绕过方式 题目 进行代码审计 可知为反序列化 整体是创建case类&#xff0c;可接受post传来的ctf值 _consturuct函数,是在函数调动前启用&#xff0c;构造了$method和$args两个变量。 _dexstruct函数在变量摧毁的时使用&#xff0c;所…

HDU - 7315 Data Generation( 2023“钉耙编程”中国大学生算法设计超级联赛第四场 D)

题目大意 Yoshinow2001 \text{Yoshinow2001} Yoshinow2001 正在为他的问题生成数据。他想要生成 { 0 , … , n − 1 } \{0,…,n−1\} {0,…,n−1} 的一个随机排列&#xff0c;因此他使用了以下算法&#xff1a; 在这里&#xff0c;我们可以假设函数 rand ⁡ ( ) m o d n \ope…

超声功率放大器基本原理和设计流程

超声功率放大器是一种将低功率信号放大到高功率信号的设备&#xff0c;是实现超声成像、治疗和检查的关键组件。它主要由功率放大电路、控制电路、保护电路等部分组成。本文将介绍超声功率放大器的技术方案&#xff0c;包括其基本原理、设计流程及注意事项。 基本原理 超声功率…

闭环排队理论简介

闭环排队理论简介 1. 系统情景2. 数学描述 在排队理论简介一文中&#xff0c;笔者详细介绍了排队理论的基本内容。在该文中&#xff0c;申请流是来自系统外部的&#xff0c;其强度&#xff08;或密度&#xff09;并不取决于系统本身&#xff0c;也不取决于系统的状态。而在本文…

网络安全法律法规

数据参考&#xff1a;CISP官方 目录 国家立法体系网络安全法解析网络安全相关法律 一、国家立法体系 1、我国的立法体系 我国的立法体系在网络空间治理中扮演着基础工作的角色。为了应对快速发展的网络技术和威胁&#xff0c;我国采取了多级立法机制来完善网络空间的法律…

【uniapp】十分钟带你封装uniapp的api请求

前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 前言 最近刚好接了个私活&#xff0c;顺便把之前做到的项目中没有写出来的功能点单独拿出来写一篇吧&#xff01; 其实在我的uniapp专栏里面写了不少关…

Kafka 入门到起飞系列 - 怎么从ISR中选出的Leader呢? Leader选举机制

上文我们讲了分区分成Leader 和 Follower两种角色&#xff0c;当Leader宕机后&#xff0c;会从ISR同步副本中选出一个分区作为leader分区继续工作&#xff0c;那么leader是怎么选出来的呢&#xff1f; 怎么从ISR中选出的Leader呢&#xff1f; Leader选举机制 比如有这么个分布…

梯度下降法和牛顿法

梯度下降法和牛顿法都是优化方法。 梯度下降法 梯度下降法和相关知识可以参考导数、偏导数、梯度、方向导数、梯度下降、二阶导数、二阶方向导数一文。梯度下降法是一种迭代地每次沿着与梯度相反方向前进的不断降低损失函数的优化方法。梯度下降只用到一阶导数的信息&#xf…

word怎么转换成pdf?分享几种转换方法

word怎么转换成pdf&#xff1f;将Word文档转换成PDF文件有几个好处。首先&#xff0c;PDF文件通常比Word文档更容易在不同设备和操作系统上查看和共享。其次&#xff0c;PDF文件通常比Word文档更难以修改&#xff0c;这使得它们在需要保护文件内容的情况下更加安全可靠。最后&a…

Linux 学习记录59(ARM篇)

Linux 学习记录59(ARM篇) 本文目录 Linux 学习记录59(ARM篇)一、IIC总线1. 概念2. IIC总线硬件连接 二、系统框图三、IIC时序1. 起始信号 / 停止信号2. 数据传输信号3. 应答信号 / 非应答信号4. 寻址信号 四、IIC协议1. 主机给从机发送一个字节(写)2. 主机给从机发送多个连续字…

Lab———Git使用指北

Lab———Git使用指北 &#x1f916;:使用IDEA Git插件实际工作流程 &#x1f4a1; 本文从实际使用的角度出发&#xff0c;以IDEA Git插件为基本讲述了如果使用IDEA的Git插件来解决实际开发中的协作开发问题。本文从 远程仓库中拉取项目&#xff0c;在本地分支进行开发&#x…

【C++】STL中list的模拟实现(增删查改,迭代器封装,运算符重载)

文章目录 前言大体框架&#xff1a; 一、节点的封装&#xff08;list_node&#xff09;二、迭代器的封装(_list_iterator)1.类模板的定义&#xff1a;2.构造函数3.前置&#xff0c;后置4.前置--&#xff0c;后置--5.解引用(operator*())6. ->重载&#xff08;operator- >…