Easy-Trans反向翻译+Excel导入最佳实践

1、概述

 实现用户excel上传、解析、对于用户输入的中文翻译为字典码或者id,实现用户输入的参数校验,最后入库。如果用户输入的参数有问题,返回校验结果给前端。

excel解析使用My-Excel组件,校验使用hibernate-validator,反向翻译组件使用easy-trans。

2、maven

 不一定使用我指定的版本,也可以使用其他的替代组件,本文主要是给大家一个思路。

<!--请注意,如果用的新版本要用org.dromara的groupId untrans-driver需要和easy-trans主版本保持一致 -->
<dependency><groupId>com.fhs-opensource</groupId><artifactId>easy-trans-untrans-driver</artifactId><version>2.2.15</version>
</dependency><!--解析excel的插件,也可以使用easy-excel --><dependency><groupId>com.github.liaochong</groupId><artifactId>myexcel</artifactId><version>4.4.2</version></dependency><!--参数校验插件 -->
<dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>6.2.5.Final</version>
</dependency>

3、校验插件代码

 首先自定义2个分组,第一个分组是对用户的必填和格式校验,第二个分组是对用户填写的数据反向翻译后,判断是否正常的校验(比如字典 有男女  他给个TS肯定翻译不到value,也要报错)。

public class ValidationGroups {public ValidationGroups() {}/*** excel导入第一遍监察*/public @interface excelImportFirst {}/*** excel导入第二遍监察*/public @interface excelImportSecond {}}

接着自定义参数校验工具类

public class ValidateUtil {private static final Validator validator =Validation.buildDefaultValidatorFactory().getValidator();/*** 通过组来校验实体类*/public static <T> String validate(T t, Class<?>... groups) {Set<ConstraintViolation<T>> constraintViolations = validator.validate(t, groups);if (constraintViolations.size() > 0) {StringBuilder validateError = new StringBuilder();for (ConstraintViolation<T> constraintViolation : constraintViolations) {validateError.append(constraintViolation.getMessage()).append(";");}return validateError.toString();}return null;}/*** 通过组来校验实体类*/public static <T> String validate(List<T> objs, Class<?>... groups) {StringBuilder validateError = new StringBuilder();boolean hasError = false;for (int i = 0; i < objs.size(); i++) {String result = validate(objs.get(i),  groups);if(result!=null){validateError.append("第" + (i+1) + "行:" + result);hasError = true;}}return hasError ? validateError.toString() : null;}}

4、easy-trans的yml配置

主要配置上db-type  支持mysql和postgresql

easy-trans:#启用redis缓存 如果不用redis请设置为falseis-enable-redis: true#启用全局翻译(拦截所有responseBody进行自动翻译),如果对于性能要求很高可关闭此配置is-enable-global: true#启用平铺模式is-enable-tile: true#字典缓存放到redis 微服务模式请开启dict-use-redis: true      #数据库类型指定,反向翻译使用      db-type: mysql

5、新增pojo,用于接收excel的数据

  支持组合唯一键,比如   财务部的王磊  财务部是org表的name  王磊是user表的name。

 比如:下面类里面的 domainId

 支持字典反向翻译,比如男女之类的 ,下面类里面的modelType

 当然也支持表里面的唯一键,比如身份证号码,手机号等。下面类里面的layeringId

package com.xhb.data.center.dgp.api.excel;import com.fhs.core.trans.anno.UnTrans;
import com.fhs.core.trans.constant.UnTransType;
import com.github.liaochong.myexcel.core.annotation.ExcelColumn;
import com.xhb.data.center.api.validate.ValidationGroups;
import lombok.Data;
import org.hibernate.validator.constraints.Length;import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;/*** 模型表excel导入POJO*/
@Data
public class ModelingLogicalTableImport {@NotBlank(message = "业务主题名称不能为空",groups = {ValidationGroups.excelImportFirst.class})@ExcelColumn(title = "主题域(*)")private String subjectName;@NotBlank(message = "主题域名称不能为空",groups = {ValidationGroups.excelImportFirst.class})@ExcelColumn(title = "业务主题(*)")private String domainName;@NotBlank(message = "数仓分层名称不能为空",groups = {ValidationGroups.excelImportFirst.class})@ExcelColumn(title = "数仓分层名称(*)")private String layeringName;@NotBlank(message = "doris集群名称不能为空",groups = {ValidationGroups.excelImportFirst.class})@ExcelColumn(title = "集群名称(*)")private String clusterName;@NotBlank(message = "doris库名称不能为空",groups = {ValidationGroups.excelImportFirst.class})@ExcelColumn(title = "所在库(*)")private String databaseName;@NotBlank(message = "模型中文名称不能为空",groups = {ValidationGroups.excelImportFirst.class})@Length(max = 64,message = "模型中文名称不能超过{max}位",groups = {ValidationGroups.excelImportFirst.class})@ExcelColumn(title = "中文名称(*)")private String chName;@NotBlank(message = "模型英文名称不能为空",groups = {ValidationGroups.excelImportFirst.class})@Length(max = 64,message = "模型英文名称不能超过{max}位",groups = {ValidationGroups.excelImportFirst.class})@ExcelColumn(title = "英文名称(*)")private String enName;@ExcelColumn(title = "数据模型(*)")private String modelTypeName;@ExcelColumn(title = "副本数(*)")private Integer replicationNum;@ExcelColumn(title = "事实表类型(*)")private String factTableTypeName;@ExcelColumn(title = "业务过程中文名称(*)")private String processName;@ExcelColumn(title = "模型描述")private String description;@NotBlank(message = "集群匹配不到数据",groups = {ValidationGroups.excelImportSecond.class})@UnTrans(type = UnTransType.SIMPLE,refs = {"clusterName", "databaseName"},tableName = "dgp_warehouse_doris_cluster c join dgp_warehouse_doris_database d on c.id=d.cluster_id",columns = {"c.name", "d.database_name"},uniqueColumn = "d.id")private String clusterDatabaseId;@NotBlank(message = "主题域匹配不到数据",groups = {ValidationGroups.excelImportSecond.class})@UnTrans(type = UnTransType.SIMPLE,refs = {"subjectName", "domainName"},tableName = "dgp_warehouse_plan_subject s join dgp_warehouse_plan_domain d on s.id=d.subject_id",columns = {"s.name", "d.name"},uniqueColumn = "d.id")private String domainId;@NotBlank(message = "数据模型匹配不到数据",groups = {ValidationGroups.excelImportSecond.class})@UnTrans(refs = "modelTypeName", type = UnTransType.DICTIONARY, dict = "dgp_modeling_model_type")private String modelType;@NotBlank(message = "数仓分层匹配不到数据",groups = {ValidationGroups.excelImportSecond.class})@UnTrans(type = UnTransType.SIMPLE,refs = {"layeringName"},tableName = "dgp_warehouse_plan_layering",columns = {"name"})private String layeringId;@UnTrans(type = UnTransType.SIMPLE,refs = {"subjectName", "domainName", "processName"},tableName = "dgp_warehouse_plan_subject s join dgp_warehouse_plan_domain d on s.id=d.subject_id join dgp_modeling_process p",columns = {"s.name", "d.name", "p.ch_name"}, uniqueColumn = "p.id")private String processId;@UnTrans(type = UnTransType.DICTIONARY,refs = {"factTableTypeName"},dict = "dgp_modeling_fact_table_type")private String factTableType;private List<ModelingLogicalColumnImport> columns = new ArrayList<>();
}

6、controller

在controller里面接收文件对象,然后转换成pojo。我下面的demo是表导入,一次导入多个表,每个表又有多个字段。所以搞了2个sheet,大多数一个sheet就行了。

7、service层代码

大致思路:先校验参数,在校验参数的方法里已经做了反向翻译了。校验不通过直接抛异常,校验通过继续下面的excel pojo转po 然后 批量入库操作。

校验参数:

1、先进行基础校验,判断必填的是否填写了,格式是否正确。

2、反向翻译

3、校验反向翻译的结果字段,比如xxid xxType。比如客户输入了一个张三,但是没匹配到张三对应的userid  客户输入了TS 但是字典里只有男女,没匹配到TS的字典码 都会在第二次校验里校验出来。

4、如果有错误,则抛异常,然后全局异常拦截后返回json给前端

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

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

相关文章

高效管理 Nginx 的利器:nginxWebUI 指南和 Docker 部署安装过程

前言 Nginx WebUI 是一个为 Nginx 提供图形化管理界面的工具。通过 WebUI&#xff0c;用户可以轻松管理 Nginx 配置&#xff0c;而无需直接编辑配置文件&#xff0c;尤其适合新手用户和频繁修改配置的场景。 官网文档&#xff1a;nginxWebUI - 文档 本文将分享为什么选择 ngin…

SpringCloud源码-openFeign

LoadBalancer默认只有nacos服务发现器 openFeign与springcloud loadbalancer的结合点 openFeign通过spring cloud loadbalancer进行负载均衡&#xff0c;spring cloud loadbalancer通过discovery client获取nacos的机器列表&#xff0c;然后底层进行负载均衡。

基于微信小程序的校园自助打印系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实…

从 ELK Stack 到简单 — Elastic Cloud Serverless 上的 Elastic 可观察性

作者&#xff1a;来自 Elastic Bahubali Shetti, Chris DiStasio 宣布 Elastic Cloud Serverless 上的 Elastic Observability 正式发布 — 一款完全托管的可观察性解决方案。 随着组织规模的扩大&#xff0c;一个能够处理分布式云环境的复杂性并提供实时洞察的可观察性解决方…

21.<基于Spring图书管理系统②(图书列表+删除图书+更改图书)(非强制登录版本完结)>

PS&#xff1a; 开闭原则 定义和背景 开闭原则&#xff08;Open-Closed Principle, OCP&#xff09;&#xff0c;也称为开放封闭原则&#xff0c;是面向对象设计中的一个基本原则。该原则强调软件中的模块、类或函数应该对扩展开放&#xff0c;对修改封闭。这意味着一个软件实体…

三、GIT与Github推送(上传)和克隆(下载)

GIT与Github推送&#xff08;上传&#xff09;和克隆&#xff08;下载&#xff09; 一、配置好SSH二、在Github创建仓库三、git克隆&#xff08;下载&#xff09;文件四、git推送&#xff08;上传&#xff09;文件到远程仓库 一、配置好SSH Git与Github上传和下载时需要使用到…

网工日记:FTP两种工作模式的区别

FTP 的主动模式和被动模式在连接建立的发起方、数据传输端口以及对网络环境的适应性等方面存在明显区别&#xff1a; 1. 连接发起方 主动模式&#xff1a;数据连接由服务器主动发起。在控制连接建立后&#xff0c;客户端通过 PORT 命令告知服务器自己用于接收数据的临时端口号…

【数字化】华为一体四面细化架构蓝图

导读&#xff1a;华为的“一体四面”企业架构设计方法是一种综合性的管理框架&#xff0c;它通过业务架构、信息架构、应用架构和技术架构的集成设计&#xff0c;构建出一个既符合业务需求&#xff0c;又具备高度灵活性和可扩展性的IT系统。这种架构设计方法强调从业务视角出发…

【linux板卡】lubancat通过vnc远程访问桌面

鲁班猫开发板通过远程VNC连接桌面&#xff1a; 硬件&#xff1a;lubancat2&#xff0c;网线 软件&#xff1a;ssh软件&#xff0c;vnc viewer 参考链接&#xff1a;https://training.eeworld.com.cn/video/38821 1、ssh连接lubancat2 &#xff0c;输入ifconfig查看ip 2、输入 …

解决Springboot整合Shiro+Redis退出登录后不清除缓存

解决Springboot整合ShiroRedis退出登录后不清除缓存 问题发现问题解决 问题发现 如果再使用缓存管理Shiro会话时&#xff0c;退出登录后缓存的数据应该清空。 依赖文件如下&#xff1a; <dependency><groupId>org.springframework.boot</groupId><arti…

2024国城杯 Web

这四道题目Jasper大佬都做了镜像可以直接拉取进行复现 https://jaspersec.top/2024/12/16/0x12%20%E5%9B%BD%E5%9F%8E%E6%9D%AF2024%20writeup%20with%20docker/ n0ob_un4er 这道题没有复现成功, 不知道为啥上传了文件, 也在 /tmp目录下生成了sess_PHPSESSID的文件, 但是就是…

el-input输入框需要支持多输入,最后传输给后台的字段值以逗号分割

需求&#xff1a;一个输入框字段需要支持多次输入&#xff0c;最后传输给后台的字段值以逗号分割 解决方案&#xff1a;结合了el-tag组件的动态编辑标签 那块的代码 //子组件 <template><div class"input-multiple-box" idinputMultipleBox><div>…

nginx 的 server 块配置解析

前后端分离&#xff08;前端 flask&#xff09;&#xff1a; # 阻止ip访问server {# default_server 是一个配置参数&#xff0c;用于指定当请求的域名&#xff08;Host 头&#xff09;没有匹配任何 server 块时&#xff0c;Nginx 应该使用哪个 server 块来处理这些请求。 lis…

Ubuntu 22.04.5 修改IP

Ubuntu22.04.5使用的是netplan管理网络&#xff0c;因此需要在文件夹/etc/netplan下的01-network-manager-all.yaml中修改&#xff0c;需要权限&#xff0c;使用sudo vim或者其他编辑器&#xff0c;修改后的内容如下&#xff1a; # Let NetworkManager manage all devices on …

‘vue-cli-service‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

这个错误信息表示系统找不到 vue-cli-service 命令&#xff0c;通常是因为 Vue 项目没有正确安装所需的依赖包。解决这个问题的步骤如下&#xff1a; 1. 确保你已经安装了依赖 首先&#xff0c;确保你在项目目录下&#xff0c;并且运行了以下命令来安装项目所需的依赖&#x…

解决virtualbox克隆ubuntu虚拟机之后IP重复的问题

找遍了国内论坛&#xff0c;没一个能解决该问题的&#xff0c;所以我自己写个文章吧&#xff0c;真讨厌那些只会搬运的&#xff0c;污染国内论坛环境&#xff0c;搜一个问题&#xff0c;千篇一律。 问题 操作系统版本为"Ubuntu 24.04 LTS" lennytest1:~$ cat /etc…

基于SpringBoot的宠物寄养系统的设计与实现(源码+SQL+LW+部署讲解)

文章目录 摘 要1. 第1章 选题背景及研究意义1.1 选题背景1.2 研究意义1.3 论文结构安排 2. 第2章 相关开发技术2.1 前端技术2.2 后端技术2.3 数据库技术 3. 第3章 可行性及需求分析3.1 可行性分析3.2 系统需求分析 4. 第4章 系统概要设计4.1 系统功能模块设计4.2 数据库设计 5.…

idea 开发Gradle 项目

在Mac上安装完Gradle后&#xff0c;可以在IntelliJ IDEA中配置并使用Gradle进行项目构建和管理。以下是详细的配置和使用指南&#xff1a; 1. 验证Gradle是否已安装 在终端运行以下命令&#xff0c;确保Gradle安装成功&#xff1a; gradle -v如果输出Gradle版本信息&#xff…

REST与RPC的对比:从性能到扩展性的全面分析

在微服务架构中&#xff0c;服务间通信是核心问题之一。常见的两种通信方式是REST&#xff08;Representational State Transfer&#xff09;和RPC&#xff08;Remote Procedure Call&#xff09;。它们各有优缺点&#xff0c;适用于不同场景。本文将从性能、扩展性、兼容性和开…

【Linux】:线程安全 + 死锁问题

&#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;Linux—登神长阶 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f49e; &#x1f49e; &#x1f49e; 1. 线程安全和重入问题&…