当前位置: 首页 > news >正文

Java中校验导入字段长度与数据库字段长度一致性

需求:使用EasyExcel导入数据时,根据数据库字段长度校验导入字段的长度。使用的数据库是mysql。若是一般的校验需求, Spring Validation 或 Hibernate Validator 即可满足。

实现步骤:

  • 获取需要校验的表,查询出字段相关信息
  • 对比导入字段与数据库字段长度,不符合则跑出异常
  • 实体字段的属性应该与数据库字段对应的驼峰命名相同,如数据库是user_age, 实体属性应是userAge;
  • 只校验字符串类型的字段

代码示例

数据库字段信息类:

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;/*** @author sjy* @date 2024/9/4 17:59* @description:*/
@Data
public class DatabaseInfoVo {@ApiModelProperty("表名")private String tableName;@ApiModelProperty("列名")private String columnName;@ApiModelProperty("字段注释")private String comment;@ApiModelProperty("字段长度")private Integer length;
}

xml查询语句示例:

<select id="findDatabaseSchemaInfo" resultType="xxxxx.vo.DatabaseInfoVo">SELECTTABLE_NAME AS tableName,COLUMN_NAME AS columnName,COLUMN_COMMENT AS comment,CHARACTER_MAXIMUM_LENGTH AS lengthFROMINFORMATION_SCHEMA.COLUMNSWHERETABLE_SCHEMA = #{useDbname}AND TABLE_NAME in ('yourtable','yourtable','yourtable','yourtable','yourtable')AND CHARACTER_MAXIMUM_LENGTH IS NOT NULLAND COLUMN_NAME NOT IN ('KSKID','KSJCXXID')
</select>

这里只需要校验固定的几张表,想要灵活的话可以修改成参数传递进来。

对比逻辑:

private final ThreadLocal<Map<String, DatabaseInfoVo>> databaseInfoLocal = new ThreadLocal<>();
// 使用完成需要释放
public void removeThreadLocal() {databaseInfoLocal.remove();}/*** 校验导入字段值与数据库字段值长度* @param dto*/private void validDatabaseWord (yourDto dto) {Map<String, DatabaseInfoVo> databaseInfoVoMap = databaseInfoLocal.get();if (CollectionUtils.isEmpty(databaseInfoVoMap)) {List<DatabaseInfoVo> databaseSchemaInfoList = yourmapper.findDatabaseSchemaInfo(useDbname);if (databaseSchemaInfoList != null) {databaseInfoVoMap = databaseSchemaInfoList.stream().filter(databaseInfoVo ->// xx表只需要校验两个字段!"table".equals(databaseInfoVo.getTableName()) ||"column1".equals(databaseInfoVo.getColumnName()) ||"column2".equals(databaseInfoVo.getColumnName())).collect(Collectors.toMap(databaseInfoVo -> toCamelCase(databaseInfoVo.getColumnName()),databaseInfoVo -> databaseInfoVo,(existing, replacement) -> existing // 处理键冲突时保留现有的值));} else {databaseInfoVoMap = Maps.newHashMap();}databaseInfoLocal.set(databaseInfoVoMap);}// 获取实体的属性Field[] fields = yourDto.class.getDeclaredFields();for (Field field : fields) {// 仅处理String类型的属性if (field.getType().equals(String.class)) {// 允许访问私有字段field.setAccessible(true);String fieldName = field.getName();if (databaseInfoVoMap.containsKey(fieldName)) {DatabaseInfoVo databaseInfo = databaseInfoVoMap.get(fieldName);if (ObjectUtil.isNotNull(databaseInfo)) {// 获取数据库列的长度int dbColumnLength = databaseInfo.getLength();try {// 获取实体属性的值Object fieldValue = field.get(dto);if (fieldValue != null) {String value = (String) fieldValue;if (value.length() > dbColumnLength) {// 如果没有引入swagger,直接使用列描述即可// throw new CheckedException(databaseInfo.getComment() + "超过长度,最大长度:" + databaseInfo.getLength());ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);String apiPropertyValue = apiModelProperty.value();// 执行处理逻辑,例如截断、抛出异常、记录日志等throw new CheckedException(apiPropertyValue + "超过长度,最大长度:" + databaseInfo.getLength());}}} catch (IllegalAccessException e) {// 处理访问异常e.printStackTrace();}}}}}}/*** 数据库字段转驼峰* @param word* @return*/public String toCamelCase(String word) {if (StrUtil.isAllBlank(word)) {return "";}StringBuilder result = new StringBuilder();boolean toUpperCase = false;for (char ch : word.toCharArray()) {if (ch == '_') {toUpperCase = true;} else {if (toUpperCase) {result.append(Character.toUpperCase(ch));toUpperCase = false;} else {result.append(Character.toLowerCase(ch));}}}return result.toString();}

Easyexcel导入逻辑省略,参考官方文档即可。

最终效果:


生命可以随心所欲,但不能随波逐流。 – 宫崎骏

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 图为科技基于昇腾AI,打造智慧工厂检测解决方案
  • 金蝶云星空查询SQL
  • 数据仓库理论知识
  • 2024/9/9 408“回头看”:b树
  • Spark-ShuffleWriter
  • 风中摇曳的小萝卜(机器学习)笔记 EM算法
  • AutoIT:强大的RPA自动化脚本神器,安装到使用的保姆级教程!
  • Matlab程序练习
  • 4千6历年高考英语试题大全ACCESS\EXCEL数据库
  • strncpy陷阱
  • 运维问题0002:SAP多模块问题-SAP系统程序在执行时,跳出“加急快件”窗口,提示:快件文档“更新已终止”从作者***收到
  • SonicWall SSL VPN曝出高危漏洞,可能导致防火墙崩溃
  • 如何修复软件中的BUG
  • 第四章 类和对象 课后训练(1)
  • 数据看板多端查看无压力,教你轻松设置响应式布局
  • codis proxy处理流程
  • Fabric架构演变之路
  • golang 发送GET和POST示例
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • js递归,无限分级树形折叠菜单
  • Just for fun——迅速写完快速排序
  • Less 日常用法
  • Lsb图片隐写
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • Python实现BT种子转化为磁力链接【实战】
  • React+TypeScript入门
  • Redis在Web项目中的应用与实践
  • spring + angular 实现导出excel
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • 初探 Vue 生命周期和钩子函数
  • 技术发展面试
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 阿里云API、SDK和CLI应用实践方案
  • ​数据结构之初始二叉树(3)
  • !!Dom4j 学习笔记
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • # 移动硬盘误操作制作为启动盘数据恢复问题
  • #Linux(Source Insight安装及工程建立)
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (STM32笔记)九、RCC时钟树与时钟 第二部分
  • (二)c52学习之旅-简单了解单片机
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (转)c++ std::pair 与 std::make
  • (转)拼包函数及网络封包的异常处理(含代码)
  • .gitignore文件使用
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .NET框架类在ASP.NET中的使用(2) ——QA
  • @ComponentScan比较
  • @JsonFormat 和 @DateTimeFormat 的区别
  • [ linux ] linux 命令英文全称及解释
  • [ 隧道技术 ] 反弹shell的集中常见方式(四)python反弹shell
  • [Angularjs]asp.net mvc+angularjs+web api单页应用之CRUD操作
  • [ANT] 项目中应用ANT