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请设置为false
  is-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给前端

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV-Python实战(6)——图相运算

一、加法运算 1.1 cv2.add() res cv2.add(img1,img2,dstNone,maskNone,dtypeNone) img1、img2&#xff1a;要 add 的图像对象。&#xff08;shape必须相同&#xff09; mask&#xff1a;图像掩膜。灰度图&#xff08;维度为2&#xff09;。 dtype&#xff1a;图像数据类型…

Leetcode打卡:查询数组中元素出现的位置

执行结果&#xff1a;通过 题目 3159 查询数组中元素出现的位置 给你一个整数数组 nums &#xff0c;一个整数数组 queries 和一个整数 x 。 对于每个查询 queries[i] &#xff0c;你需要找到 nums 中第 queries[i] 个 x 的位置&#xff0c;并返回它的下标。如果数组中 x 的出…

向量组学习

向量组的秩及其线性组合 线性相关性 先看a1,a2 如果这两个向量不对应成比例的话,那必然内部不可能存在多余的向量,也就是无关. 主元所在的列都是独立向量 ,最大无关组就是b1,b2,b4,但这个是初等行变换后的,题目要的是A的,与之对应的就是a1,a2,a4 方程组解的结构

影视仓最新接口+内置本包方法的研究(2024.12.27)

近日喜欢上了研究影视的本地仓库内置&#xff0c;也做了一个分享到了群里。 内置本地仓库包的好处很明显&#xff0c;当前线路接口都是依赖网络上的代码站存放&#xff0c;如果维护者删除那就GG。 虽然有高手制作了很多本地包&#xff0c;但推送本地包到APP&#xff0c;难倒一片…

redis相关数据类型介绍

当然&#xff0c;Redis 作为一个高性能的键值存储系统&#xff0c;提供了多种数据类型来支持不同的应用场景。 1. String&#xff08;字符串&#xff09; • 定义&#xff1a;Redis 最基本的数据类型&#xff0c;用于存储字符串值。 • 操作&#xff1a;SET、GET、INCR、DECR、…

教师管理系统

大概功能&#xff1a; 1.显示所有教师 2.按姓名查找教师 3.按工号查找教师 4.增加教师 5.删除教师 6.退出 数据会保存到 txt 文件里面 姓名&#xff1a;必须是中文 手机号码&#xff1a;必须是11位&#xff0c;必须是数字 效果展示&#xff1a; 代码展示&#xff1a; Teache…

lombok-macros

GITHUB 地址 LTPP-GIT 地址 官方文档 API 文档 一组提供 Lombok 类似功能的 Rust 宏。 安装 要使用此 crate&#xff0c;可以运行以下命令&#xff1a; cargo add lombok-macros用法 use lombok_macros::*;/// 定义一个结构体&#xff0c;使用 Lombok 宏派生所需的方法 #…

uniapp开发微信小程序实现获取“我的位置”

1. 创建GetLocation项目 使用HBuilder X创建一个项目GetLocation,使用Vue3。 2. 在腾讯地图开放平台中创建应用 要获取位置,在小程序中需要使用腾讯地图或是高德地图。下面以腾讯地图为例。 (1)打开腾讯地图开放平台官方网址:腾讯位置服务 - 立足生态,连接未来 (2)注册…

Docker基础知识 Docker命令、镜像、容器、数据卷、自定义镜像、使用Docker部署Java应用、部署前端代码、DockerCompose一键部署

目录 1.Docker 2.镜像和容器 2.1 定义 2.2 开机自动启动容器 3.docker命令 3.1 docker run 参数说明 3.2 常见命令 3.3 命令演示 3.4 命令别名 4.Docker命令详解 5.数据卷 5.1 定义 5.2 数据卷的相关命令 5.3 数据卷命令 5.4 挂载本地目录或文件 5.4.1 定义 5.4.2 mysql容器目录…

Linux | Ubuntu零基础安装学习cURL文件传输工具

目录 介绍 检查安装包 下载安装 手册 介绍 ‌cURL是一个利用URL语法在命令行下工作的文件传输工具&#xff0c;首次发行于1997年‌‌12。cURL支持多种协议&#xff0c;包括FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3…

c# 2024/12/27 周五

6《详解类型、变量与对象》36 详解类型、变量与对象 _1_哔哩哔哩_bilibili

yarn list --pattern vuex-module-decorators

dgqdgqdeMac-mini spid-admin % yarn list --pattern vuex-module-decorators yarn list v1.22.22 └─ vuex-module-decorators0.16.1 ✨ Done in 0.24s.好的&#xff0c;这段代码是一个典型的 Vuex 模块定义&#xff0c;使用了 vuex-module-decorators 库。这个库为 Vuex 提…

uniapp 判断多选、选中取消选中的逻辑处理

一、效果展示 二、代码 1.父组件: :id=“this.id” : 给子组件传递参数【id】 @callParentMethod=“takeIndexFun” :给子组件传递方法,这样可以在子组件直接调用父组件的方法 <view @click="$refs.member.open()"

IDEA自己常用的几个快捷方式(自己的习惯)

TOC 背景 换工作了, 新的IDEA, 又要重新设置自己的快捷方式了. 灵感 1.这些个性话的配置应该是可以导出的. 然后在新的IDEA直接导入就行了, 感觉应该是有这个功能. 就是这个文件: <keymap version"1" name"Personal KeyMap" parent"$default…

学习AndroidPerfetto基础一

1.哔哩哔哩学习视频&#xff1a; Android Perfetto 基础和案例分享_哔哩哔哩_bilibili 2.Perfetto的简单介绍 Perfetto 是一个用于性能检测进而追踪分析的生产级开源工具 Perfetto提供上帝视角&#xff0c;背后需要整个Android系统的知识储备 Perfetto由Google开发&#x…

ffmpeg: stream_loop报错 Error while filtering: Operation not permitted

问题描述 执行ffmpeg命令的时候&#xff0c;报错&#xff1a;Error while filtering: Operation not permitted 我得命令如下 ffmpeg -framerate 25 -y -i /data/workerspace/mtk/work_home/mtk_202406111543-l9CSU91H1f1b3/tmp/%08d.png -stream_loop -1 -i /data/workerspa…

快速掌握Elasticsearch检索之二:滚动查询获取全量数据(golang)

Elasticsearch8.17.0在mac上的安装 Kibana8.17.0在mac上的安装 Elasticsearch检索方案之一&#xff1a;使用fromsize实现分页 1、滚动查询的使用场景 滚动查询区别于上一篇文章介绍的使用from、size分页检索&#xff0c;最大的特点是&#xff0c;它能够检索超过10000条外的…

StableAnimator模型的部署:复旦微软提出可实现高质量和高保真的ID一致性人类视频生成

文章目录 一、项目介绍二、项目部署模型的权重下载提取目标图像的关节点图像&#xff08;这个可以先不看先用官方提供的数据集进行生成&#xff09;提取人脸&#xff08;这个也可以先不看&#xff09;进行图片的生成 三、模型部署报错 一、项目介绍 由复旦、微软、虎牙、CMU的…

【深度学习】Java DL4J基于 CNN 构建车辆识别与跟踪模型

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

如何在短时间内读懂复杂的英文文献?

当我们拿起一篇文献开始阅读时&#xff0c;就像是打开了一扇通往未知世界的大门。但别急着一头扎进去&#xff0c;咱们得像个侦探一样&#xff0c;带着疑问去探险。毕竟&#xff0c;知识的海洋深不可测&#xff0c;不带点“装备”怎么行&#xff1f;今天就聊聊&#xff0c;平时…