JAVA批量操作MYSQL数据的细节

java mysql数据库实现批量插入 /** * 批量插入 * * @param tableName * @param datas * @return */ public boolean insertBatch(String tableName, List<Map<String, Object>> datas) { PreparedStatement prepared = null; Connection co... 阅读详情

java通过jdbc批量add,update,delete数据其实是在使用jdbc的batch相关的API。

但是底层怎么实现的?

mysql新增一张测试用的表:

create table student
(
    id     bigint      not null        primary key,
    stu_no bigint      not null,
    name   varchar(10) null,
    constraint stu_no   unique (stu_no)
);

批量插入

代码

  Connection conn = null;
  @Before
  public void beforeClass() throws Exception {
    // 注册mysql数据库jdbc连接驱动,
    //高版本的mysql底层使用了SSL协议加密,会导致wireshark抓到的数据包不是明文,所以在这配置不加密,方便观察底层文本。
    //rewriteBatchedStatements=true,配置后才能真的打开mysql批量操作功能
    String url = "jdbc:mysql://localhost:3306/test?useSSL=false&&rewriteBatchedStatements=true";
    String user = "root";
    String password = "rootroot";
    conn = DriverManager.getConnection(url, user, password);
  }

  @Test
  public void testAdd() throws SQLException {
    String SQL = "insert into student(id, stu_no, name) VALUES (?,?,?)";
    PreparedStatement pstmt = conn.prepareStatement(SQL);

    for (int i = 1; i < 20000; i++) {
      pstmt.setLong(1, i);
      pstmt.setInt(2, i);
      pstmt.setString(3, "张三" + i);
      pstmt.addBatch();
      //每1000个sql执行一次。
      if (i % 1000 == 0) {
        int[] count = pstmt.executeBatch();
        //每个sql执行成功后影响的数据行数。和单个执行的sql的返回意义一样
        System.out.println("count:" + Arrays.toString(count));
        pstmt.clearBatch();
      }

    }

  }

底层

使用wireshark抓包看看底层数据: 

可见mysql的JDBC实现其实是将多个单独的insert语句拼接在了一起,一次性发送给mysql服务器。每批次的数量和我们调用executeBatch的流程吻合,1000个。

形式是insert into table(xx) values (xx),(xx),(xx); 的sql语句 。

返回的结果

执行插入语句的时候,mysql返回的结果是按照顺序匹配的。数组1000个代表着1000个sql的结果。

-2即SUCCESS_NO_INFO。阅读注释可知:代表SQL执行成功。但是服务端不返回影响行数。我想大概原因是因为sql最后变形成了一条合并的sql,没法单独返回了。 这一点也可以通过观察wireshark的RESPONSE得出结论。每个批次一个sql也只有一次返回应答。

批量修改

如果不是批量新增,而是批量修改。而且是独立不同的update语句呢?

代码

  @Test
  public void testUpdate() throws SQLException {
      String SQL = "update student set name=? where id=?";
      PreparedStatement pstmt = conn.prepareStatement(SQL);
      for (int i = 1; i < 11; i++) {
        pstmt.setString(1, "李四");
        pstmt.setLong(2, i);
        pstmt.addBatch();
      }
      int[] count = pstmt.executeBatch();
      System.out.println("count:" + Arrays.toString(count));

  }

底层

10个update的sql都是独立的,所以并不能简单像insert一样拼接成一个SQL。直接就是所有update sql用分号拼接上一次性发给server端。但是Server端的Response却是10次,不像刚才insert一样只有一次。

返回的结果

每个SQL对应的影响数据行数都正确返回了。

批量操作里有异常 

如果一批次操作里有一条sql执行失败呢?

代码

@Test
  public void testUpdateException() {
    try {
      String SQL = "update student set name=? where id=?";

      PreparedStatement pstmt = conn.prepareStatement(SQL);

      for (int i = 1; i < 11; i++) {
        if (i == 5) {
          //第五个SQL的时候name长度11,过长,会导致sql报错。
          pstmt.setString(1, "张三张三张三张三张三张");
        } else {
          pstmt.setString(1, "张三");
        }
        pstmt.setLong(2, i);
        pstmt.addBatch();
      }
      int[] count = pstmt.executeBatch();
      System.out.println("count:" + Arrays.toString(count));
    } catch (BatchUpdateException e) {
      System.out.println(e.getMessage());
      System.out.println("count:" + Arrays.toString(e.getUpdateCounts()));
    } catch (SQLException e) {
      throw new RuntimeException(e);
    }
  }

底层 

从 java.sql.Statement#executeBatch方法的注释来看,这种情况的结果取决于数据库的驱动实现。

要么从错误的SQL开始全部不执行,要们跳过错误的SQL继续执行后面的SQL。

从底层的数据看,mysql的实现是:从错误的SQL开始全部不执行

返回的结果

这里就非常奇怪。无法理解为什么有-1, -3的个数也不对。感觉是驱动实现的BUG。BatchUpdateException.getUpdateCounts returns unexpected value -1 · Issue #450 · awslabs/aws-mysql-jdbc · GitHub 

批量操作和事务的关系

有很多人将批量操作和事务混淆一起说。似乎批量操作的sql都必须放在一个事务里。其实这2件事根本没有任何关系。批量操作的sql既可以是每个都是单独的事务,也可以是放在一个事务里。

至少在网络交互层面,其实没有多大区别。因为批量操作真正提速的关键点是:将多个sql合并到了一次网络交互里!

只不过我们在实际的业务中,提前将数据切成小批次的数据后,以每个小批次为一个事务,失败后整体重试。在代码实现上要简单很多。不用去比对到底是哪条sql异常了。

代码 

  @Test
  public void testUpdateExceptionTransaction() {
    try {
      String SQL = "update student set name=? where id=?";
      conn.setAutoCommit(false);
      PreparedStatement pstmt = conn.prepareStatement(SQL);
      for (int i = 1; i < 11; i++) {
        if (i == 5) {
          pstmt.setString(1, "张三张三张三张三张三张");
        } else {
          pstmt.setString(1, "张三");
        }
        pstmt.setLong(2, i);
        pstmt.addBatch();
      }
      int[] count = pstmt.executeBatch();
      conn.commit();
      System.out.println("count:" + Arrays.toString(count));
    } catch (BatchUpdateException e) {
      System.out.println(e.getMessage());
      System.out.println("count:" + Arrays.toString(e.getUpdateCounts()));
    } catch (SQLException e) {
      throw new RuntimeException(e);
    }
  }

底层

网络交互几乎没有却别。当然数据库因为整体一个事务的原因,其实底层一条sql也没真正执行成功。

返回的结果 

和每条sql的单独事务返回的结果一样。但是这里要警觉,其实因为统一一个事务的原因,其实一条都没成功!! 

MySQL大批量造数据 有时候往数据库里批量造数据,是为了某些测试前的必要条件。例如导出Excel报表功能、性能压测时的压测数据等。一般批量造数据有以下几种方式1、通过接口请求方式批量造数据2、开发脚本(Java、Python等)进行批量造数据3、使用Jmeter的MySQL脚本发起批量造数据4、通过MySQL的存储过程造数据本篇采用MySQL的存储过程方式来进行批量造数据。存储过程(StoredProcedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。... 阅读详情

相关推荐

java 实现数据批量处理,达到一定数量或者达到一定时间去处理

实际中可能有这样的应用场景,得到一个记录不需要立即去处理它,而是等累积到一定数量时再批量处理它们。

nsa65223的专栏 2559

java批量修改数据库数据

这句sql的意思是,更新display_order 字段,如果id=1 则display_order 的值为3,如果id=2 则 display_order 的值为4,如果id=3 则 display_order 的值为5。确保sql语句仅执行需要修改的行数,这里只有3条数据进行更新,而where子句确保只有3行数据执行。replace into 操作本质是对重复的记录先delete 后insert,如果更新的字段不全会将缺失的字段置为缺省值。一条记录update一次,这样性能很差,也很容易造成阻塞。

2301_78008478的博客 3427

PTPX功耗分析实战——从脚本配置到报告解读

本文详细介绍了PTPX功耗分析的全流程,从脚本配置到报告解读,帮助工程师快速掌握芯片设计中的功耗估算技术。文章涵盖了环境搭建、波形文件处理、功耗报告解析等关键环节,并提供了实战经验和优化建议,特别适合需要提升PTPX功耗分析效率的开发者。

weixin_29248313的博客 279

Java实现向MySQL数据库批量更新数据的常见方法

Java实现向MySQL数据库批量更新数据的几种常见方法详细介绍。

m0_53654272的博客 8721

双目相机立体匹配算法概述(含Python代码)

立体匹配任务是计算机视觉中的一个重要问题,旨在从一对具有相同场景的图像中估计每个像素的视差(disparity)。本文对现有的传统算法和深度学习算法进行了综述,以便于各位选择合适的立体匹配算法用于深度估计或三维建模。

m0_59257547的博客 8291

合宙Air780EP速连OneNET:AT+MQTT应用指南

本文详细讲解了合宙Air780EP使用AT指令通过MQTT接入OneNET的过程。

2401_82812461的博客 1389

Java通过JDBC向数据库批量插入数据(MySQL为例)

注:本文仅供学习参考,作者水平有限,如有错误还请指正! 文章目录1、 JDBC的批量处理语句:2、批量指向SQL语句的情况:3、关于本案例的注意事项:4、驱动程序5、案例源码          在数据库中需要大量插入或更新记录时,可以使用java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。 1、 JDBC的批量处理语句: addBatch(String):添加需要批量处理的SQL语句或是参数; e

Etui۹(・༥・´)و的博客 6642

ENVI 5.6 + Sarscape 5.2 保姆级教程:哨兵一号数据处理全流程(含DEM自动下载)

本文提供ENVI 5.6与Sarscape 5.2处理哨兵一号数据的完整实战教程。详细介绍了从数据导入、研究区裁剪、DEM自动下载与集成,到核心的配准、滤波及地理编码全流程,最终生成可用于定量分析的地理编码后向散射系数图。重点演示了DEM数据在SAR处理中的关键作用与自动获取方法,帮助用户快速掌握SAR数据基础处理技能。

coffee的博客 682

java 批处理 大量数据的增删改

java 快速处理超大数据的增删改

qq_40426135的博客 2198

173、LLC谐振变换器的PCB设计实战(布线)

LLC谐振变换器PCB设计实战要点 LLC谐振变换器的PCB设计核心在于控制寄生参数,避免高频振铃和EMI问题。功率回路需确保电流路径最短且紧耦合,谐振电容焊盘需加宽以减少发热。驱动走线应独立于功率回路,避免干扰,并合理控制宽度和长度。变压器绕组结构影响共模噪声,建议原边在外层并加屏蔽铜箔。地平面设计需根据功率等级选择整块或分割,大功率下功率地与信号地应单点连接。谐振电流采样推荐四端开尔文电阻以减少电感干扰。散热需优化铜皮和过孔布局,功率器件优先放置顶层。布局应先确定谐振腔,再排布控制电路。经验上需实测寄生

Jack010169的博客 46

GEE训练教程:基于Sentinel-2卫星的归一化建筑指数(NDBI)等的进行城市扩张分析

本文介绍利用Sentinel-2卫星数据和谷歌地球引擎平台监测印度卡姆鲁普都会区2018-2024年城市扩张的方法。通过计算归一化建筑指数(NDBI)、植被指数(NDVI)和水体指数(MNDWI),采用多阈值规则识别建设用地,并量化不同年份的城市扩张面积。代码实现了从数据预处理、指数计算到面积统计的完整流程,为城市扩张研究提供了可复制的技术方案。关键参数包括年份选择、云覆盖阈值和分类阈值,均可根据研究需求调整。该方法能有效追踪城市边界变化,为城市规划提供数据支持。

此星光明博客 135

Mybatis批量添加实现

一、引言 Mybatis可以直接传入一个集合,通过标签将集合中的数据遍历出来实现批量新增 不同的数据库批量新增有区别,如下实现两种方式的批量新增 二、实现 2.1映射文件 insert command_content(content,command_id) values(#{content},#{commandId)) <!-- mysql 批

简书的专栏 1817

热力学仿真软件:Fluent_(13).燃烧与化学反应仿真

燃烧模型在热力学仿真软件中扮演着至关重要的角色。Fluent 提供了多种燃烧模型,包括层流预混燃烧模型、湍流预混燃烧模型、非预混燃烧模型、部分预混燃烧模型等。这些模型可以帮助用户模拟不同的燃烧过程,从而更好地理解燃烧现象和优化燃烧系统设计。

kkchenjj的博客 1252

以CSV文件导入MySQL的批量数据插入操作之Java操作

项目最近涉及将excel中的数据导入到MySQL数据库,由于Excel中数据并不规范,需要进行二次加工处理,所以不能讲excel直接导入数据库。 编程语言:Java 平台框架:Spring、Spring MVC、MyBatis

天才姐夫的专栏 5147

C#量化交易的市场数据采集与分析:从0到1构建你的‘数据雷达’——对比5大神器,代码实战全解析!

数据是量化交易的‘氧气’,而好的数据采集与分析是你的‘呼吸机’!本文5大神器+代码实战,总有一款适合你!(本文代码均经过测试,但请根据实际需求调整!

java专栏 730

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Java代码操作MySQL数据库——JDBC编程

1. JDBC的初识 2. 准备工工作 3. 增加数据 4. 修改数据 5. 删除数据 6. 查询数据

mgzdwm的博客 2920

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

java中批量插入Mysql千万级别数据

import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Date; /** * Mysql千万级别数据批量插入 * * 1)配置my.ini文件 * 文...

努力做一名优秀的程序员 8638

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

JAVA怎么批量更新mysql_java 关于批量更新操作的实现

批量更新操作批量更新逻辑:底层真正的批量更新(一次请求发送批量更新语句)底层循环发送语句(假批量更新)—本质上就是一条一条更新批量更新逻辑判断JdbcTemplateJdbcUtils.supportsBatchUpdates(ps.getConnection())—判断连接是否支持批量更新publicint[] batchUpdate(Stringsql,finalBatchPreparedSt...

weixin_36360005的博客 2442

MySql 及MyBatis数据的批量操作

mysql及mubatis的批量操作

xunming的专栏 2037

批量向mysql写入数据_Java批量向MySql写入数据

(原载:javaeye)实现Java批量插入数据库数据,在javaeye中看到过几篇关于实现Java批量插入数据库数据,转载时没有找到,就自己写一下,也算是对自己学习过程中所遇到过的问题做一个总结。一般关于批量向数据库插入数据都采用PreparedStatement、Statement…………也包括直接使用JDBCAPI、框架…………也看到过几篇关于这些内容的总结,及大家的评论,以下为我总结的关于...

weixin_29825861的博客 1405

JAVA怎么批量更新mysql_java 批量添加、批量更新 操作数据库

(1)三种插入操作的方法1.1 利用for循环的批量插入示例xmlinsert into test_user (u_name,create_date) value (#{userName},SYSDATE())示例代码:for (int i = 1; i <= num; i++) {User user = new User();user.setUserName("a" + i);user.s...

weixin_30863333的博客 1768

Java向mysql批量存储数据_java大批量数据导入(MySQL)

© 版权声明:本文为博主原创文章,转载请注明出处最近同事碰到大批量数据导入问题,因此也关注了一下。大批量数据导入主要存在两点问题:内存溢出和导入速率慢。内存溢出:将文件中的数据全部取出放在集合中,当数据过多时就出现Java内存溢出,此时可通过调大JVM的最大可用内存(Xmx)解决,但终究不是王道。MySQL支持一条SQL语句插入多条记录的操作,并且效率比单条插入快的不是一点点;但是MySQL一次可...

weixin_39967096的博客 1356

Java 通过JDBC连接并操作Mysql数据库

使用Java连接数据库需要使用JDBC驱动。JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。以下是使用方法 一、安装配置好mysql 二、下载驱动包 : http://dev.mysql.com/downloads/connector/j/

Leezitao的博客 5万+

mysql之批量修改数据

文章目录1. 对于某个字段,批量修改数据的方式2. jdbc中批量插入数据的方式2.1 jdbc中标准插入多条数据的方式2.2 jdbc中批量插入多条数据的方式 1. 对于某个字段,批量修改数据的方式 mysql> select * from emp; +----+----------+-----+------+-------+----------+ | id | name | age | sex | depId | hiredate | +----+----------+-----+-

mercies的博客 6733

java mysql批量添加数据_Java 批量插入数据库(MySQL)数据

实现Java批量插入数据库数据,在javaeye中看到过几篇关于实现Java批量插入数据库数据,转载时没有找到,就自己写一下,也算是对自己学习过程中所遇到过的问题做一个总结。一般关于批量向数据库插入数据都采用PreparedStatement、Statement…………也包括直接使用JDBC API、框架…………也看到过几篇关于这些内容的总结,及大家的评论,以下为我总结的关于批量向数据库插入数据。...

weixin_33398049的博客 3881

MySQL - 批量操作优化:insert、update 批量执行的性能提升技巧

MySQL 批量操作优化指南 摘要 本文深入探讨 MySQL 批量操作(INSERT/UPDATE)的性能优化技巧,帮助开发者解决高吞吐系统中的数据处理瓶颈。文章对比了单条循环操作的性能缺陷,详细介绍了四种高效批量插入方案: 多值INSERT:单次网络往返,适用于中小批量数据 JDBC Batch(推荐方案):自动分批执行,支持事务控制 LOAD DATA INFILE:极速文件导入,适合海量数据 ORM框架支持:MyBatis Plus/JPA的批量操作封装 同时提供Java实现示例,包括MyBatis、

千淘万漉虽辛苦,吹尽狂沙始到金 2万+
上一篇: Docker pull 拉不到镜像的简单解决方法
下一篇: MYSQL间隙锁导致的死锁
大飞Tobi
博客等级 码龄16年 54粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值