java实现根据 表索引 批量新增或更新数据信息

目的

        通过数据库名、表名实现动态添加活更新数据。添加或更新由唯一索引判断。

实现

        思路

                查询数据库表的唯一索引-CSDN博客

                根据数据库表名动态查询表字段-CSDN博客

                达梦数据库根据唯一索引批量新增或更新数据-CSDN博客

                将数据转换为sql语句需要的格式

                完善代码,实现功能

        实现代码

                将数据转换为sql语句需要的格式

    /*** 将数据转换为sql语句需要的格式** @param tableName   表名* @param dataList    接受到的数据* @param uniqueIndex 索引列* @param <T>         泛型类* @return 转换后的数据*/public static <T> Map<String, Object> cvtDataTypeByTable2(String tableName, List<T> dataList, List<String> uniqueIndex) {//根据表名查询字段列表Map<String, List<String>> columnsByTable = QueryColumnsByTableName.queryColumnsByTableName(tableName);//创建存储返回信息的retMapMap<String, Object> retMap = new LinkedHashMap<>();//获取所有的表字段List<String> columns = columnsByTable.get(tableName);//获取需要更新的字段,即索引字段外的其它所有字段List<String> updateColumns = columns.stream().filter(column -> !uniqueIndex.contains(column)).collect(Collectors.toList());//处理传入的数据List<List<Map<String, Object>>> columnsValueList = dataList.stream().map(data -> {List<Map<String, Object>> singleColumnValue = columns.stream()//对数据列表进行流式处理.map(column -> { // 对每个列进行映射操作try {//将列名转换为驼峰式或小写String columnName = Convert2CamelCaseOrLowerCase.convertToCamelCaseOrLowerCase(column);//根据列名获取数据对象的值Object columnValue = getValueByFieldName(data, columnName);return  new LinkedHashMap<String, Object>() {{//将列名作为键,列名作为值放入Map中put("name", column);// 将列值作为键,列值作为值放入Map中put("value", columnValue);}};} catch (NoSuchFieldException | IllegalAccessException e) {// 处理异常,例如记录日志或抛出更具体的异常e.printStackTrace();return null; // 或者抛出异常}}).collect(Collectors.toList());//将映射结果收集为Listreturn singleColumnValue; //返回单个列的值列表}).collect(Collectors.toList());//将映射结果收集为ListretMap.put("columns", columns);retMap.put("uniqueIndex", uniqueIndex);retMap.put("data", columnsValueList);retMap.put("updateColumns", updateColumns);return retMap;}

        service层代码

package org.springblade.modules.system.service;import org.apache.poi.ss.formula.functions.T;import java.util.List;public interface I类名{/*** 更新或新增第三方传入数据** @param dataName  数据库名* @param tableName 表名* @param dataList  传入数据* @return 是否成功*/<T> boolean updateOrSaveDsfData(String dataName, String tableName, List<T> dataList);}

        serevice实现类代码

        

package org.springblade.modules.system.service.impl;import lombok.extern.slf4j.Slf4j;
import org.springblade.modules.system.helper.CvtDataTypeByTable;
import org.springblade.modules.system.mapper.DataBodyMapper;
import org.springblade.modules.system.service.IDsfSjCcService;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;
import java.util.Map;/*** 存储第三方传入信息 实现类*/
@Service
@Slf4j
public class 类名 implements I类名 {@Resourceprivate DataBodyMapper dataBodyMapper;@Overridepublic <T> boolean updateOrSaveDsfData(String dataName, String tableName, List<T> dataList) {if (dataList == null || dataList.isEmpty()) {// 返回 false,并且不抛出异常,而是将异常处理交给调用者return false;}try {// 查询唯一索引List<String> unique = dataBodyMapper.selectUniqueIndex_DM(dataName, tableName);List<String> uniqueIndex = new ArrayList<>();if (unique != null && !unique.isEmpty()) {for (String row : unique) {uniqueIndex.addAll(Arrays.asList(row.split(",")));}}//将收到的数据转为存储所需格式Map<String, Object> formattedDataMap = CvtDataTypeByTable.cvtDataTypeByTable2(tableName, dataList, uniqueIndex);//从Map中获取正确的类型,避免强制类型转换List<Object> data = (List<Object>) formattedDataMap.get("data");List<String> uniqueIndexList = (List<String>) formattedDataMap.get("uniqueIndex");List<String> columns = (List<String>) formattedDataMap.get("columns");List<String> updateColumns = (List<String>) formattedDataMap.get("updateColumns");// 执行批量插入或更新操作dataBodyMapper.batchInsertOrUpdate(tableName, data, uniqueIndexList, columns, updateColumns);} catch (Exception e) {// 可以考虑记录日志而不是打印堆栈跟踪e.printStackTrace();return false;}return true;}}

        mapper层代码

package org.springblade.modules.system.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springblade.modules.system.entity.DataBodyEntity;import java.util.List;/*** 数据主体 Mapper 接口** @author BladeX* @since 2022-12-12*/
public interface DataBodyMapper extends BaseMapper<DataBodyEntity> {/*** 插入或更新** @param tableName     表名* @param dataList      表数据* @param uniqueIndex   索引字段* @param columns       表字段* @param updateColumns 更新字段*/// @InterceptorIgnore(tenantLine = "true")void batchInsertOrUpdate(String tableName, List<Object> dataList, List<String> uniqueIndex, List<String> columns, List<String> updateColumns);
}

        mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.springblade.modules.system.mapper.DataBodyMapper"><insert id="batchInsertOrUpdate" parameterType="java.util.List">MERGE INTO ${tableName} dstUSING(<foreach collection="dataList" item="data" open="(" separator=" UNION ALL " close=")">SELECT<foreach collection="data" item="dt" separator=",">#{dt.value} AS ${dt.name}</foreach>FROM dual</foreach>)srcON<foreach collection="uniqueIndex" item="unique_index_column" open="(" separator=" and" close=")">dst.${unique_index_column} = src.${unique_index_column}</foreach>WHEN MATCHED THENUPDATE SET<foreach collection="updateColumns" item="column" separator=",">dst.${column} = src.${column}</foreach>WHEN NOT MATCHED THENINSERT<foreach collection="columns" item="field" open="(" separator="," close=")">${field}</foreach>VALUES<foreach collection="columns" item="column" open="(" separator="," close=")">src.${column}</foreach></insert></mapper>

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

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

相关文章

maven常用打包命令

1.背景 2.代码 1 mvn常用命令 一般情况下对于一个maven项目&#xff0c;cd切换到当前项目路径下&#xff0c;执行如下示例命令即可对项目进行打包。 mvn clean install mvn -U clean package -Dmaven.test.skiptrue mvn clean package -Dmaven.test.skiptrue -P prod mvn cle…

JavaScript数组操作指南:20个精通操作技巧指南

splice、 slice、 pop 和 shift。数组的排序方法是稳定且非原地算法的吗&#xff1f;要记住所有 JavaScript 数组方法以及它们之间的区别并不容易。它们的名称相似&#xff0c;就好像直接从同义词词典中提取一样。 这个数组速查表列出了 JavaScript 中通常需要的所有数组方法&…

Gson使用Object接收长数字问题

近期发现公司同事在使用Gson对数字进行反序列列化时出现丢失精度的问题&#xff0c;在这里搬运一下&#xff0c;做个记录~ 现象 使用Gson反序列化长Long数字(大于16位),如果用Object类型来接收则会丢失精度。 Gson会将数字反序列化为double类型,double类型本身就容易丢精度。…

小程序基础

小程序基础 1. 认识什么是小程序 什么是微信小程序 微信小程序是一种运行在微信内部的 轻量级 应用程序。 在使用小程序时 不需要下载安装&#xff0c;用户 扫一扫 或 搜一下 即可打开应用。它也体现了 “用完即走” 的理念&#xff0c;用户不用关心安装太多应用的问题。它…

weak的实现原理

iOS 在运行时维护着一个全局的弱引用表&#xff0c;该表是一个 hash 表&#xff0c;hash表的 key 是 对象本身&#xff0c;value 是指向该对象的所有 weak 指针的地址数组。 /**全局的弱引用表&#xff0c;本质是一个hash结构&#xff0c;对象本身作为key, 存储weak修饰的指…

大模型训练经验

1.模型训练好后预测全是起始符号。 解决办法&#xff1a;训练数据的输入输出去掉起始符号。 2.模型训练后学不到有效信息。 加大epoch&#xff0c;我加大到了1000。 3.模型训练后预测没有结束符&#xff0c;暂时未解&#xff0c;另外&#xff0c;发现当训练不足时&#xff…

Metasploit安装及使用教程(非常详细)从零基础入门到精通,看完这一篇就够了。

通过本篇文章&#xff0c;我们将会学习以下内容&#xff1a; 1、在Windows上安装Metasploit 2、在Linux和MacOS上安装Metasploit 3、在Kali Linux中使用 Metasploit 4、升级Kali Linux 5、使用虚拟化软件构建渗透测试实验环境 6、配置SSH连接 7、使用SSH连接Kali 8、配…

如何学习自然语言处理之语言模型

自然语言处理&#xff08;NLP&#xff09;是一种人工智能技术&#xff0c;它使计算机能够理解和处理人类语言。而语言模型是NLP中的一个重要概念&#xff0c;主要是用来估测一些词的序列的概率&#xff0c;即预测p(w1, w2, w3 … wn)&#xff0c;其中一个应用就是句子的生成。 …

JVM运行流程

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;JavaEE &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; JVM 1. 运行流程2. 运行时数据区2.1 堆&am…

ubuntu新建ap热点并分享

测试环境ubuntu16,只有一台笔记本电脑&#xff0c;不插网线&#xff0c;无线网卡既连wifi&#xff0c;又作为热点 1.方法1 直接手动新建ap热点 参考https://jingyan.baidu.com/article/ea24bc39b03fc6da62b331f0.html https://jingyan.baidu.com/article/363872ecd8f35d6e4ba…

机试指南:Ch5:线性数据结构 Ch6:递归与分治

文章目录 第5章 线性数据结构1.向量 vector2.队列 queue(1)队列的特点、应用(2)基本操作(3)例题例题1&#xff1a;约瑟夫问题2 &#xff08;难度&#xff1a;中等&#xff09; (4)习题习题1&#xff1a;排队打饭 &#xff08;难度&#xff1a;中等&#xff09; 3.栈 stack(1)栈…

前端 JS 经典:Content-type 详解

1. 什么是 Content-Type Content-Type 是 HTTP 协议中的一个请求头或响应头字段&#xff0c;用于指示发送或接收的实体的媒体类型&#xff0c;告诉服务器或客户端如何解析和处理请求或响应的主体部分。 2. Content-Type 的构成 Content-Type 由两部分组成&#xff1a;媒体类型…

视频在线压缩

video2edit 一款免费的在线视频编辑软件&#xff0c;可以进行视频合并、视频剪辑、视频压缩以及转换视频格式等。 链接地址&#xff1a;在线视频编辑器和转换器 - 编辑&#xff0c;转换和压缩视频文件 打开视频压缩页面&#xff0c;上传想要压缩视频&#xff0c;支持MP4&…

收入稳步增长 助力持续发展 尼康发布截至2024年3月财年第三季度财报

近日&#xff0c;尼康截至2024年3月财年的第三季度&#xff08;2023年10月1日-2023年12月31日&#xff09;财报正式发布。数据显示&#xff0c;尼康集团第三财季销售收入共计1977亿日元&#xff0c;较去年同期上涨300亿日元&#xff0c;涨幅约17.9%。其中影像业务领域&#xff…

Java面试题:解释Java内存模型中的内存顺序规则,Java中的线程组(ThreadGroup)的工作原理,Java中的FutureTask的工作原理

引言 在Java开发领域&#xff0c;内存模型、多线程和并发是三个至关重要的概念&#xff0c;它们直接影响到程序的性能、稳定性和可扩展性。作为面试官&#xff0c;考察候选人对这些概念的理解和应用能力是评估其技术水平的重要手段。本文将提供三道涉及这些核心知识点的面试题…

视频记录仪_基于联发科MT6762的智能4G记录仪方案

智能记录仪采用联发科强劲八核处理器&#xff0c;12nm制程工艺的记录仪具便是满足这些需求的理想选择。搭载4GB32GB内存&#xff0c;并运行Android 11.0操作系统&#xff0c;这款记录仪具展现出强劲的性能表现。 首先&#xff0c;这款记录仪具具备优秀的视频录制功能。它能完整…

WPS如何共享文件和文件夹

1 WPS共享单个文件 用WPS打开要分享的文件&#xff0c;点击右上角的“分享”键&#xff0c;选择上传到云端。 之后点击“创建并分享”&#xff0c;即可分享该文档。 2 WPS创建共享文件夹 2.1 如何共享文件夹 首先打开WPS&#xff0c;点击左上角的首页。在首页栏中&#…

Ubuntu系统下DPDK环境搭建

目录 一.虚拟机配置1.添加一个网卡(桥接模式)2.修改网卡类型3.修改网卡名称4.重启虚拟机5.查看网卡信息6.dpdk配置内存巨型页 三 DPDK源代码下载和编译1.下载源代码2.解压源代码3.安装编译环境4.编译5.设置dpdk的环境变量6.禁止多队列网卡7.加载igb_uio模块8.网卡绑定9.验证测试…

Vue3自定义文章列表组件

一、Vue3的代码展示 <template><div><div v-for"article in articles" :key"article.id" class"article-card"><div class"author-info"><img :src"article.avatar" alt"Author Avatar&qu…

Android 验证启动模式

文章目录 Android 验证启动模式查看任务栈launchModestandardsingleTopsingleTasksingleInstance Intent标记FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TASK 和 FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TOPFLAG_ACTIVITY_SINGLE_TOP Android 验证启动模式 查看任务栈 可…