【Java】一个批量更新插入数据到MySQL的工具类

分享自己写的一个工具类,可以批量sqlreplace更新插入数据到DB

dbUtils.java 文件

java 复制代码
package com.tuling.DB;
import java.sql.*;
import java.util.*;
/**
 * SQL工具类,提供数据库操作相关功能
 */
public class dbUtils {
  /**
   * 执行REPLACE INTO操作,批量插入或更新数据
   *
   * @param tableName 表名
   * @param data      数据列表,每个Map代表一行数据
   * @param conn      数据库连接
   * @return 受影响的行数总和
   * @throws SQLException 数据库操作异常
   */
  public static int sqlReplace(String tableName, List<Map<String, Object>> data, Connection conn) throws SQLException {
    // 参数验证
    if (tableName == null || tableName.trim().isEmpty()) {
      throw new IllegalArgumentException("表名不能为空");
    }
    if (data == null || data.isEmpty()) {
      return 0;
    }
    // 获取第一行的列名
    Map<String, Object> firstRow = data.get(0);
    Set<String> columns = firstRow.keySet();
    int columnCount = columns.size(); // 列数
    List<String> columnList = new ArrayList<>(columns); // 列名列表
    if (columns.isEmpty()) {
      return 0;
    }
    // 构造 SQL 语句
    StringBuilder sqlBuilder = new StringBuilder("REPLACE INTO ");// 添加表名
    sqlBuilder.append(tableName).append(" (");
    // 添加字段名
    for (int i = 0; i < columnCount; i++) {
      if (i > 0) {
        sqlBuilder.append(", "); // 添加逗号分隔
      }
      sqlBuilder.append(columnList.get(i));
    }
    sqlBuilder.append(") VALUES (");
    // 添加占位符
    for (int i = 0; i < columnCount; i++) {
      if (i > 0) {
        sqlBuilder.append(", ");
      }
      sqlBuilder.append("?");
    }
    // 添加结束符
    sqlBuilder.append(")");
    String sql = sqlBuilder.toString();
    System.out.println(sql);  // 打印SQL语句
    try (PreparedStatement ps = conn.prepareStatement(sql)) { // 创建预编译语句对象
      for (Map<String, Object> row : data) {// 遍历每行数据
        int index = 1;
        for (String column : columnList) {//遍历字段
          Object value = row.get(column);// 获取字段值
          if (value == null) {
            ps.setNull(index, Types.OTHER); // 可根据需要替换为具体类型
          } else {
            ps.setObject(index, value);// 设置参数值
          }
          index++;
        }
        ps.addBatch();// 添加批处理
      }
      int[] results = ps.executeBatch();// 执行批处理
      return Arrays.stream(results).sum(); // 返回受影响的总行数
    }
  }
  /**
   * 验证数据行结构是否一致
   *
   * @param data            数据列表
   * @param expectedColumns 预期的列名集合
   * @throws IllegalArgumentException 如果数据结构不一致
   */
  private static void validateDataStructure(List<Map<String, Object>> data, Set<String> expectedColumns) {
    if (data == null) {
      return;
    }
    // 验证每行数据的列名
    for (int i = 0; i < data.size(); i++) {
      Map<String, Object> row = data.get(i);
      if (row == null) {
        throw new IllegalArgumentException("第 " + (i + 1) + " 行数据不能为null");
      }
      Set<String> rowColumns = row.keySet();
      if (!rowColumns.equals(expectedColumns)) {
        throw new IllegalArgumentException("第 " + (i + 1) + " 行数据结构与第一行不一致");
      }
    }
  }
}

然后调用上述的方法:

java 复制代码
package com.tuling.part1;
import com.tuling.DB.dbUtils;
import java.sql.*;
import java.util.*;

public class Demo {
  public static void main(String[] args) throws ClassNotFoundException, SQLException {
    Class.forName("com.mysql.cj.jdbc.Driver");
    String url = "jdbc:mysql://xxxxx:3306/economy";
    String username = "xxxx";
    String password = "xxxx";
    Connection conn = DriverManager.getConnection(url,username,password);
    //构建数据
    List<Map<String,Object>> data = new ArrayList<>();
    Map<String,Object> row = new HashMap<>();
    row.put("id",1);
    row.put("name","zhangsan");
    row.put("age",22);
    data.add(row);
    //插入数据
    dbUtils.sqlReplace("testing",data,conn);
  }
}

效果就是

bash 复制代码
REPLACE INTO testing (name, id, age) VALUES (1, "zhangsan", 22)
相关推荐
m0_6399069410 分钟前
MySQL 实现分布式锁:悲观锁、乐观锁、唯一索引锁
数据库·分布式·mysql
努力努力再努力wz15 分钟前
【Lua入门系列】从动态类型到变量作用域:彻底理解 local、全局变量与跨文件访问
开发语言·junit·lua
Rain的Java大神之路19 分钟前
100 亿条数据如何快速写入 MySQL?从 231 天到 3.5 小时,我把面试官问懵了
java·后端·面试
程序猿乐锅22 分钟前
面向对象练习:图书借阅系统里的封装、抽象类与多态
开发语言·前端·数据库·后端·python·学习·1024程序员节
xyouyuweizhu26 分钟前
Java IO 流详解:流的作用、流的划分与标准输入输出流
java·python·php
沐晓时光39 分钟前
C语言入门,深入理解指针(6)
c语言·开发语言
略略略咯咯42 分钟前
33333
开发语言·windows·python
垆边人似月.1 小时前
第三篇:函数、文件与异常处理 / Functions, Files & Exception Handling
开发语言·python
云和数据.ChenGuang1 小时前
项目打开后没有主类
开发语言·人工智能·langchain·1024程序员节
范同学~1 小时前
项目添加水印
java·前端·javascript