前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >10. 批量插入

10. 批量插入

作者头像
Devops海洋的渔夫
发布2022-01-17 14:53:01
1K0
发布2022-01-17 14:53:01
举报
文章被收录于专栏:Devops专栏Devops专栏

10. 批量插入

前言

上一章节,我们使用 PreparedStatement 操作了 BLOB 字段,下面我们再来看看批量插入的操作。

批量插入

1. 批量执行SQL语句

当需要成批插入或者更新记录时,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率

JDBC的批量处理语句包括下面三个方法:

  • addBatch(String):添加需要批量处理的SQL语句或是参数;
  • executeBatch():执行批量处理语句;
  • clearBatch(): 清空缓存的数据

通常我们会遇到两种批量执行SQL语句的情况:

  • 多条SQL语句的批量处理;
  • 一个SQL语句的批量传参;

2. 高效的批量插入

举例:向数据表中插入20000条数据

  • 数据库中提供一个goods表。创建如下:
代码语言:javascript
复制
CREATE TABLE goods(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
  • 测试插入数据
代码语言:javascript
复制
mysql> insert into goods(name) values('test');
Query OK, 1 row affected (0.00 sec)

mysql> insert into goods(name) values('test1');
Query OK, 1 row affected (0.01 sec)

mysql> select * from goods;
+----+-------+
| id | NAME  |
+----+-------+
|  1 | test  |
|  2 | test1 |
+----+-------+
2 rows in set (0.00 sec)

mysql> 
2.1 实现层次一:使用Statement插入20000条数据
代码语言:javascript
复制
    //实现层次一:使用Statement
    //向数据表中插入20000条数据
    @Test
    public void test01() throws Exception {
        //1.获取连接
        Connection conn = JDBCUtils.getConnection();
        Statement st = conn.createStatement();

        //2.执行插入数据
//        String sql = "insert into goods(name) values('test1')";
//        st.executeUpdate(sql);
        //向数据表中插入20000条数据
        for (int i = 1; i <= 20000; i++) {
            String sql = "insert into goods(name) values('test " + i +"')";
            st.executeUpdate(sql);
        }
    }

测试执行如下:

执行之后的mysql数据:

代码语言:javascript
复制
mysql> select * from goods limit 10;
+----+--------+
| id | NAME   |
+----+--------+
|  3 | test1  |
|  4 | test1  |
|  5 | test 1 |
|  6 | test 2 |
|  7 | test 3 |
|  8 | test 4 |
|  9 | test 5 |
| 10 | test 6 |
| 11 | test 7 |
| 12 | test 8 |
+----+--------+
10 rows in set (0.00 sec)

mysql> select count(1) from goods limit 10;
+----------+
| count(1) |
+----------+
|    20002 |
+----------+
1 row in set (0.00 sec)
2.2 实现层次二:使用PreparedStatement插入20000条数据

在上面可以看到耗时挺久的,下面我们改用 PreparedStatement 来插入数据看看。

代码语言:javascript
复制
//实现层次二:使用PreparedStatement插入20000条数据
@Test
public void test02() throws Exception {
    //1.记录执行开始时间
    long start = System.currentTimeMillis();

    //2.获取数据库连接
    Connection conn = JDBCUtils.getConnection();

    //3.预编译SQL
    String sql = "insert into goods(name) values(?)";
    PreparedStatement ps = conn.prepareStatement(sql);

    //4.设置插入数据以及执行
    for (int i = 1; i <= 20000; i++) {
        ps.setString(1, "test" + i);
        ps.executeUpdate();
    }

    //5.计算结束时间
    long end = System.currentTimeMillis();
    System.out.println("花费的时间为:" + (end - start));//

    //6.关闭资源
    JDBCUtils.closeResource(conn, ps);
}

测试执行如下:

2.3 实现层次三:优化效率,将逐条SQL执行 改为 批处理执行
  • 配置mysql启用批处理执行 rewriteBatchedStatements=true
代码语言:javascript
复制
user=root
password=*****
url=jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false
driverClass=com.mysql.cj.jdbc.Driver
  • 测试代码
代码语言:javascript
复制
/**
 * 实现层次三:使用PreparedStatement插入20000条数据
 * 修改1:使用 addBatch() / executeBatch() / clearBatch()
 * 修改2:mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理的支持。
 *         ?rewriteBatchedStatements=true 写在配置文件的url后面
 *
 *
 * @throws Exception
 */
@Test
public void test03() throws Exception {
    //1.记录执行开始时间
    long start = System.currentTimeMillis();

    //2.获取数据库连接
    Connection conn = JDBCUtils.getConnection();

    //3.预编译SQL
    String sql = "insert into goods(name) values(?)";
    PreparedStatement ps = conn.prepareStatement(sql);

    //4.设置插入数据以及执行
    for (int i = 1; i <= 20000; i++) {
        ps.setString(1, "test" + i);

        //执行批处理
        //1.“攒”sql
        ps.addBatch();
        if(i % 500 == 0){ // 当达到500,则开始批处理
            //2.执行
            ps.executeBatch();
            //3.清空
            ps.clearBatch();
        }
    }

    //5.计算结束时间
    long end = System.currentTimeMillis();
    System.out.println("花费的时间为:" + (end - start));//

    //6.关闭资源
    JDBCUtils.closeResource(conn, ps);
}

执行测试如下:

2.4 实现层次四:优化效率,将批处理的多次提交 设置为 最后统一 commit() 提交
代码语言:javascript
复制
/**
 * 实现层次四:优化效率,将批处理的多次提交 设置为 最后统一 commit() 提交
 * 使用Connection 的 setAutoCommit(false)  /  commit()
 *
 * @throws Exception
 */
@Test
public void test04() throws Exception {
    //1.记录执行开始时间
    long start = System.currentTimeMillis();

    //2.获取数据库连接
    Connection conn = JDBCUtils.getConnection();

    //1.设置为不自动提交数据
    conn.setAutoCommit(false);

    //3.预编译SQL
    String sql = "insert into goods(name) values(?)";
    PreparedStatement ps = conn.prepareStatement(sql);

    //4.设置插入数据以及执行
    for (int i = 1; i <= 20000; i++) {
        ps.setString(1, "test" + i);

        //执行批处理
        //1.“攒”sql
        ps.addBatch();
        if(i % 500 == 0){ // 当达到500,则开始批处理
            //2.执行
            ps.executeBatch();
            //3.清空
            ps.clearBatch();
        }
    }

    //2.提交数据
    conn.commit();

    //5.计算结束时间
    long end = System.currentTimeMillis();
    System.out.println("花费的时间为:" + (end - start));//

    //6.关闭资源
    JDBCUtils.closeResource(conn, ps);
}

测试执行如下:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 海洋的渔夫 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 10. 批量插入
    • 前言
      • 批量插入
        • 1. 批量执行SQL语句
        • 2. 高效的批量插入
    相关产品与服务
    云数据库 SQL Server
    腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档