【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)
相关推荐
在坚持一下我可没意见2 小时前
Spring 后端安全双剑(上篇):JWT 无状态认证 + 密码加盐加密实战
java·服务器·开发语言·spring boot·后端·安全·spring
就像风一样抓不住2 小时前
SpringBoot静态资源映射:如何让/files/路径访问服务器本地文件
java·spring boot·后端
缪懿2 小时前
javaEE:多线程,单列模式和生产者消费者模型
java·单例模式·java-ee
乾元2 小时前
从命令行到自动诊断:构建 AI 驱动的故障树与交互式排障机器人引言
运维·开发语言·网络·人工智能·华为·自动化
qq_2153978972 小时前
shell 脚本部署docker 服务MySQL 5.7
mysql·adb·docker
deng-c-f2 小时前
C/C++内置库函数(6):C++中类什么时候使用静态变量
开发语言·c++
启山智软2 小时前
【单体系统与分布式系统是两种根本不同的软件架构模式】
java·vue.js·spring boot·后端·spring
奈何不吃鱼2 小时前
【安装配置教程】在linux部署java项目
java·linux·intellij-idea·jar