MySQL批量入库的几种方式详解

  • 1. MySQL批量入库概述
  • 2. Hutool封装jdbc方式
  • 3. Jdbc直接或批量执行方式
  • 4. MyBatis批量入库方式
  • 5. MySQL批量入库总结

1. MySQL批量入库概述

最近压测一款mysql持久化工具,目前市面上mysql批量入库方式有很多,这里分别对常用的几种方式进行压测对比分析,比如列举了hutool工具封装的jdbc方式,jdbc直接执行与批量执行的方式,以及常用的mybatis方式。

2. Hutool封装jdbc方式

Hutool-db是一个在JDBC基础上封装的数据库操作工具类,通过包装,使用ActiveRecord思想操作数据库。在Hutool-db中,使用Entity(本质上是个Map)代替Bean来使数据库操作更加灵活,同时提供Bean和Entity的转换提供传统ORM的兼容支持。

数据库(Hutool-db):https://hutool.cn/docs/#/db/%E6%A6%82%E8%BF%B0

测试结论,hutool批量入库,数据量:10000,耗时:7.38秒,吞吐量:1357

测试环境准备
1.安装数据库,执行初始化脚本:batch-ddl.sql

-- ID、姓名、性别、年龄、Email、电话、住址。
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID主键',`name` varchar(64) NOT NULL COMMENT '姓名',`sex` varchar(4) NOT NULL COMMENT '男,女',`age` int(3) NOT NULL COMMENT '年龄',`email` varchar(64) DEFAULT NULL COMMENT '邮箱',`phone` varchar(64) DEFAULT NULL COMMENT '电话',`address` varchar(64) DEFAULT NULL COMMENT '地址',`deleted` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除 0 未删除 1 删除 默认是0',`create_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '创建人账号id',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '更新人账号id',`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`) USING BTREE,KEY `idx_name_age` (`name`,`age`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='用户表';select * from user;select count(*) from user;

2.创建maven项目,引入依赖:hutool-all,mysql-connector-java

        <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.10</version></dependency><!--mysql数据库驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version></dependency><!-- mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.6</version></dependency>

代码配置实现
1.创建配置:db.setting

## db.setting文件url = jdbc:mysql://127.0.0.1:3306/user_db?characterEncoding=utf8
user = root
pass = 123456## 可选配置
# 是否在日志中显示执行的SQL
showSql = false
# 是否格式化显示的SQL
formatSql = false
# 是否显示SQL参数
showParams = false
# 打印SQL的日志等级,默认debug,可以是info、warn、error
sqlLevel = error

2.代码实现
HutoolBatchSave

package com.zrj.maven.assembly.demo.dbutils;import cn.hutool.core.util.IdUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;import java.sql.SQLException;/*** hutool批量入库* 数据量:10000,耗时:7.38秒,吞吐量:1357** @author zrj* @since 2022/11/25**/
public class HutoolBatchSave {public static void main(String[] args) {hutoolBatchSave();}/*** hutool批量入库* 1.安装数据库,执行初始化脚本:batch-ddl.sql* 2.创建maven项目,引入依赖:hutool-all,mysql-connector-java* 3.创建配置:db.setting* 4.测试验证*/private static void hutoolBatchSave() {int count = 10000;Db db = Db.use();long start = System.currentTimeMillis();System.out.println("Hutool批量入库开始:" + start);try {for (int i = 0; i < count; i++) {//生成的是不带-的字符串,类似于:b17f24ff026d40949c85a24f4f375d42String simpleUUID = IdUtil.simpleUUID();db.insertForGeneratedKey(Entity.create("user").set("name", simpleUUID).set("sex", "男").set("age", 18).set("email", "jerry@hello.com").set("phone", "123456789").set("address", "北京欢迎你"));}} catch (SQLException e) {e.printStackTrace();}long end = System.currentTimeMillis();System.out.println("Hutool批量入库结束:" + end);System.out.println("Hutool批量入库耗时:" + (end - start));}
}

3. Jdbc直接或批量执行方式

Jdbc提供两种方式,一种是直接执行,另一种是批量执行(每1000笔提交一次事务)。

Jdbc批量入库
采用JDBC直接处理,数据量:10000,耗时:7.38秒,吞吐量:1357
采用JDBC批处理,数据量:10000,耗时:7.38秒,吞吐量:1357

环境依赖参考上一策略。

JdbcBatchSave

package com.zrj.maven.assembly.demo.dbutils;import cn.hutool.core.util.IdUtil;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;/*** Jdbc批量入库* 采用JDBC直接处理,数据量:10000,耗时:6.689秒,吞吐量:1494.9* 采用JDBC批处理,数据量:10 0000,耗时:2.271秒,吞吐量:44,033** @author zrj* @since 2022/11/25**/
public class JdbcBatchSave {private static String url = "jdbc:mysql://localhost:3306/user_db?useServerPrepStmts=false&rewriteBatchedStatements=true&useUnicode=true&amp;characterEncoding=UTF-8";private static String user = "root";private static String password = "123456";private static String drive = "com.mysql.jdbc.Driver";/*** Jdbc批量入库* 1.安装数据库,执行初始化脚本:batch-ddl.sql* 2.创建maven项目,引入依赖:hutool-all,mysql-connector-java* 3.创建配置:db.setting* 4.测试验证*/public static void main(String[] args) {//jdbcBatchSaveNoExecuteBatch();jdbcBatchSaveExecuteBatch();}/*** 采用JDBC批处理(开启事务、无事务)* 无批量提交,数据量:10 0000,耗时:2.271秒,吞吐量:44,033*/public static void jdbcBatchSaveExecuteBatch() {System.out.println("采用JDBC批处理(开启事务、无事务)");//定义连接、statement对象Connection conn = null;PreparedStatement pstmt = null;try {//1. 获取连接对象//加载jdbc驱动Class.forName(drive);//连接mysqlconn = DriverManager.getConnection(url, user, password);//将自动提交关闭conn.setAutoCommit(true);//2. 定义sql语句//String sql = "insert into contract(`name`, `code`) values(?,?)";String sql = "insert into `user_db`.`user`( `name`, `sex`, `age`, `email`, `phone`, `address`, `deleted`, `create_id`, `create_time`, `update_id`, `update_time`) " +"VALUES (?, 'boy', 18, 'jerry@hello.com', '123456789', 'beijing', 0, 0, '2022-11-25 11:17:12', 0, '2022-11-25 11:17:12')";//3. 为sql语句赋值pstmt = conn.prepareStatement(sql);long start = System.currentTimeMillis();System.out.println("Jdbc批量入库开始:" + start);//每次提交1000条,循环10次int cycle = 10;//循环次数int execute = 10000;//每次提交次数long beginNumber = 0;//起始idlong endNumber = beginNumber + execute;//每次循环插入的数据量for (int i = 0; i < cycle; i++) {while (beginNumber < endNumber) {//生成的是不带-的字符串,类似于:b17f24ff026d40949c85a24f4f375d42String simpleUUID = IdUtil.simpleUUID();pstmt.setString(1, simpleUUID);//添加到同一个批处理中pstmt.addBatch();beginNumber++;}//执行批处理pstmt.executeBatch();//边界值自增1000endNumber += execute;}long end = System.currentTimeMillis();System.out.println("Jdbc批量入库结束:" + end);System.out.println("Jdbc批量入库耗时:" + (end - start));} catch (Exception e) {e.printStackTrace();} finally {close(pstmt, conn);}}/*** 采用JDBC直接处理(开启事务、关闭事务)* 无批量提交,数据量:10000,耗时:6.689秒,吞吐量:1494.9*/public static void jdbcBatchSaveNoExecuteBatch() {System.out.println("采用JDBC直接处理(开启事务、关闭事务)");//定义连接、statement对象int count = 10000;Connection conn = null;PreparedStatement pstmt = null;try {//1. 获取连接对象//加载jdbc驱动Class.forName(drive);//连接mysqlconn = DriverManager.getConnection(url, user, password);//将自动提交关闭conn.setAutoCommit(true);//2. 定义sql语句//String sql = "insert into contract(`name`, `code`) values(?,?)";String sql = "insert into `user_db`.`user`( `name`, `sex`, `age`, `email`, `phone`, `address`, `deleted`, `create_id`, `create_time`, `update_id`, `update_time`) " +"VALUES (?, 'boy', 18, 'jerry@hello.com', '123456789', 'beijing', 0, 0, '2022-11-25 11:17:12', 0, '2022-11-25 11:17:12')";//3. 为sql语句赋值pstmt = conn.prepareStatement(sql);long start = System.currentTimeMillis();System.out.println("Jdbc批量入库开始:" + start);for (int i = 0; i < count; i++) {//生成的是不带-的字符串,类似于:b17f24ff026d40949c85a24f4f375d42String simpleUUID = IdUtil.simpleUUID();pstmt.setString(1, simpleUUID);pstmt.execute();}long end = System.currentTimeMillis();System.out.println("Jdbc批量入库结束:" + end);System.out.println("Jdbc批量入库耗时:" + (end - start));} catch (Exception e) {e.printStackTrace();} finally {close(pstmt, conn);}}private static void close(PreparedStatement pstmt, Connection conn) {if (pstmt != null || conn != null) {try {conn.close();pstmt.close();} catch (SQLException e) {e.printStackTrace();}}}
}

4. MyBatis批量入库方式

MyBatis具有方便的扩展性,与业务代码解耦,动态sql等等高扩展特性,是目前使用非常广泛的orm插件,一般与spring集成,ssm项目,但是其性能缺有些场景下不如jdbc,验证参考。

MyBatis批量入库: 数据量:10000,耗时:23.951秒,吞吐量:417.5

环境依赖参考上一策略(batch-ddl.sql,引入依赖:hutool-all,mybatis,mysql-connector-java)。

创建配置:UserMapper,mybatis-config.xml,UserMapper.xml
UserMapper

package com.zrj.maven.assembly.demo.mapper;import org.apache.ibatis.annotations.Param;/*** Descriptation** @author zrj* @since 2022/11/25**/
public interface UserMapper {void insertUser(@Param("name") String name);
}

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- mybatis的主配置文件 -->
<configuration><!-- 配置环境 --><environments default="mysql"><!-- 配置mysql的环境--><environment id="mysql"><!-- 配置事务的类型--><transactionManager type="JDBC"></transactionManager><!-- 配置数据源(连接池) --><dataSource type="POOLED"><!-- 配置连接数据库的4个基本信息 --><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/user_db"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><!--注意:这里需要注意一下,使用xml配置方式的时候放开xml配置,必须注释掉注解配置,使用注解配置的时候放开注解配置,注释掉xml配置。--><!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 --><mappers><mapper resource="mapper/UserMapper.xml"/></mappers><!-- 在使用基于注解的 Mybatis 配置时,请移除 xml 的映射配置(IUserDao.xml) --><!--<mappers>--><!--<mapper class="com.mybatis.dao.BookDao"></mapper>--><!--</mappers>-->
</configuration>

UserMapper.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="com.zrj.maven.assembly.demo.mapper.UserMapper"><insert id="insertUser">INSERT INTO `user_db`.`user`(`name`, `sex`, `age`, `email`, `phone`, `address`, `deleted`, `create_id`, `create_time`, `update_id`, `update_time`)VALUES (#{name}, 'girl', 18, 'jerry@hello.com', '123456789', 'beijing', 0, 0, '2022-11-25 11:17:12', 0, '2022-11-25 11:17:12');</insert>
</mapper>

MyBatisBatchSave

package com.zrj.maven.assembly.demo.dbutils;import cn.hutool.core.util.IdUtil;
import com.zrj.maven.assembly.demo.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.IOException;
import java.io.InputStream;/*** MyBatis批量入库* 数据量:10000,耗时:23.951秒,吞吐量:417.5** @author zrj* @since 2022/11/25**/
public class MyBatisBatchSave {public static void main(String[] args) {myBatisBatchSave();}/*** MyBatis批量入库* 1.安装数据库,执行初始化脚本:batch-ddl.sql* 2.创建maven项目,引入依赖:hutool-all,mybatis,mysql-connector-java* 3.创建配置:UserMapper,mybatis-config.xml,UserMapper.xml* 4.测试验证*/private static void myBatisBatchSave() {int count = 10000;InputStream in = null;SqlSession session = null;try {// 1.读取配置文件in = Resources.getResourceAsStream("mybatis-config.xml");// 2.创建SqlSessionFactory工厂SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();SqlSessionFactory factory = builder.build(in);// 3.使用工厂生产SQLSession对象session = factory.openSession(true);// 4.使用SQLSession创建Dao接口的代理对象UserMapper userMapper = session.getMapper(UserMapper.class);// 5.使用代理对象执行方法long start = System.currentTimeMillis();System.out.println("MyBatis批量入库开始:" + start);for (int i = 0; i < count; i++) {//生成的是不带-的字符串,类似于:b17f24ff026d40949c85a24f4f375d42String simpleUUID = IdUtil.simpleUUID();userMapper.insertUser(simpleUUID);}long end = System.currentTimeMillis();System.out.println("MyBatis批量入库结束:" + end);System.out.println("MyBatis批量入库耗时:" + (end - start));} catch (IOException e) {e.printStackTrace();} finally {try {// 6.释放资源session.close();in.close();} catch (IOException e) {e.printStackTrace();}}}}

5. MySQL批量入库总结

采用hutool批量入库, 数据量:10000, 耗时:7.38秒, 吞吐量:1357(次之)
采用JDBC直接处理, 数据量:10000, 耗时:6.689秒, 吞吐量:1494.9(其次)
采用JDBC批处理, 数据量:100000,耗时:2.271秒, 吞吐量:44033(最高)
采用MyBatis批量入库: 数据量:10000, 耗时:23.951秒, 吞吐量:417.5(最差)

MySQL批量入库的几种方式详解相关推荐

  1. mysql 删除数据表中数据_Mysql-删除数据表-三种方式详解

    Mysql 删除数据表的三种方式详解 用法: 1.当你不再需要该表时, 用 drop; 2.当你仍要保留该表,但要删除所有记录时, 用 truncate; 3.当你要删除部分记录或者有可能会后悔的话, ...

  2. 运用python的方式_对Python使用mfcc的两种方式详解

    1.Librosa import librosa filepath = "/Users/birenjianmo/Desktop/learn/librosa/mp3/in.wav" ...

  3. 全站仪与计算机之间的数据传输,必看!全站仪数据传输的三种方式详解,都安排得明明白白(上)...

    原标题:必看!全站仪数据传输的三种方式详解,都安排得明明白白(上) 科力达全站仪数据传输 一般而言,全站仪的数据传输方式有三种,分别是通过串口.USB.SD卡三种方式,因为电脑配置等因素的不同,一些数 ...

  4. 前端实现动画的6种方式详解

    前端实现动画的6种方式详解 一.总结 一句话总结:一般是css样式改变加setInterval 二.[前端动画]实现动画的6种方式 通常在前端中,实现动画的方案主要有6种: javascript直接实 ...

  5. IDEA安装阿里巴巴编码规范插件的两种方式详解(在线安装和离线安装)

    这篇文章主要介绍了IDEA安装阿里巴巴编码规范插件的两种方式详解(在线安装和离线安装),本文通过截图给大家展示的非常详细,需要的朋友可以参考下 目录 1.在线安装: 2.离线安装: IDEA安装阿里巴 ...

  6. Spring中bean的执行初始化和销毁方法的4种方式详解

    一.引入 在java的实际开发过程中,我们可能需要在spring实例化一个bean的过程中,使用到初始化一个对象(bean)后立即初始化(加载)一些数据,或者在销毁一个对象之前进行执行一些事情等等. ...

  7. python连接mysql三种方式_用 Python 连接 MySQL 的几种方式详解

    每个学 Python 的都有必要学好一门数据库,不管你是做数据分析,还是网络爬虫,Web 开发.亦或是机器学习,你都离不开要和数据库打交道,而 MySQL 又是最流行的一种数据库,这篇文章介绍 Pyt ...

  8. 【Linux】部署Springboot项目到Linux服务器以及linux服务器下载文件的三种方式详解

    Linux学习之路 初识Linux Linux内核 由芬兰人林纳斯·托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写 Linux 是一套免费使用和自由传播的类Unix操作系 ...

  9. java clone方法_干货满满:Java中创建对象的五种方式详解

    通常来说,对象具有状态和行为,变量用来表明对象的状态,方法表明对象所具有的行为. 作为Java开发者,我们通常都是使用依赖管理系统,比如Spring去创建Java对象,但使用管理系统创建对象并不是唯一 ...

最新文章

  1. android银行卡匹配、详情展开动画、仿爱奇艺视频拖拽、扫码识别手机号等源码...
  2. C++控制台没有引用的头文件也会编译的原因
  3. [转载] 人工智能:一种现代方法——第1章 绪论
  4. python筛选含变量的特定行_Python SQL从特定变量字段中选择行
  5. TensorFlow中的Nan值的陷阱
  6. php selenium下拉列表,Selenium+java - 下拉框处理
  7. php文件覆盖相同文件,为什么这个PHP代码在打开时会覆盖文件内容?
  8. 获取设置套接字选项:getsockopt, setsockopt
  9. 无线路由器连接电信光纤宽带光猫设置方法(转)
  10. PLSQL_海量数据处理系列7_DBSM_STATS
  11. C++——最长公共子串
  12. 根据CTP接口计算现手、增仓、开平、对手盘 (2)
  13. 澳门科技大学计算机专业研究生,澳门科技大学 计算机专业
  14. 「模拟8.19 A嚎叫..(set) B主仆..(DFS) C征程..(DP+堆优化)」
  15. 牛客在线编程101-93 盛水最多的容器
  16. LVS的Tun模式(隧道模式)的实现
  17. java中的变量是什么_什么是java变量,java变量是什么
  18. win10安装redis及redis客户端使用方法
  19. 关于springcloud中eureka server端配置的一些总结
  20. 5G无线网节能关键技术

热门文章

  1. Android开机向导启动流程分析
  2. springboot 如何打war
  3. Python学习教程:正态你还不会吗?这期的Python教程你肯定能学会
  4. 2021小微企业补贴条件
  5. python基金预测分析_基金定投选星期几更划算?[python统计分析]
  6. 2022CoCa: Contrastive Captioners are Image-Text Fountion Models
  7. ddr42400和2660混插_时至今日,DDR42400的马甲内存条为何不值得购买了?
  8. Attempt to reset the display driver and recover from timeout failed
  9. 前端面试题必考(四)- HTTP短连接,长连接(keep-alive),websocket,postmessage
  10. IIS误删了默认网站,恢复方法