目的
? ? ? ? 通過數據庫名、表名實現動態添加活更新數據。添加或更新由唯一索引判斷。
實現
? ? ? ? 思路
? ? ? ? ? ? ? ??查詢數據庫表的唯一索引-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>