Java 3种批量插入更新操作的效率横向比较

以前总是说批量插入和更新的效率比非批量的要高,但是到底高多少,没有评估过,今天我就具体的测试下

(1)三种插入操作的方法

1.1 利用for循环的批量插入

示例xml

    <insert id="insertUser">
        insert into test_user (u_name,create_date) value (#{userName},SYSDATE())
    </insert>

示例代码:

for (int i = 1; i <= num; i++) {
    User user = new User();
    user.setUserName("a" + i);
    user.setCreateDate(new Date());
    userDao.insertUser(user);
}

1.2 采用jdbc

示例代码:

        Connection conn;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://192.168.0.200:3306/xxx", "root", "root");
            conn.setAutoCommit(false);
            String sql = "insert into test_user (u_name,create_date) value (?,SYSDATE())";
            PreparedStatement prest = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
                    ResultSet.CONCUR_READ_ONLY);
            conn.setAutoCommit(false);

            for (int i = 1; i <= 100; i++) {
                prest.setString(1, "a" + i);
                prest.addBatch();
            }
            prest.executeBatch();
            conn.commit();


            conn.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

1.3 采用mybatis的批量插入方法

其实也是根据一个list 拼接成一个sql
示例xml

    <insert id="batchInsertList">
        insert into test_user(u_name,create_date)
        values
        <foreach item="item" index="index" collection="userList" separator=",">
            (#{item.userName},SYSDATE())
        </foreach>
    </insert>

示例代码

        List<User> userList = new ArrayList<User>();

        for (int i = 1; i <= num; i++) {
            User user = new User();
            user.setUserName("a" + i);
            user.setCreateDate(new Date());
            userList.add(user);
        }
        userDao.batchInsertList(userList);

数据量分别是10,100,300,1000,5000条数据


数量级别:10
批量插入耗时:141
非批量插入耗时:93
jdbc批量插入耗时:195

数量级别:100
批量插入耗时:164
非批量插入耗时:970
jdbc批量插入耗时:718

数量级别:300
批量插入耗时:355
非批量插入耗时:3030
jdbc批量插入耗时:1997

数量级别:500
批量插入耗时:258
非批量插入耗时:5355
jdbc批量插入耗时:2974

数量级别:1000
批量插入耗时:422
非批量插入耗时:8787
jdbc批量插入耗时:6440

数量级别:5000
批量插入耗时:870
非批量插入耗时:43498
jdbc批量插入耗时:30368


这里写图片描述

总体看来,效率排序
mybatis批量插入 > jdbc批量插入 > 循环调用insert语句

(2)三种批量更新的方法

2.1 利用for循环批量更新

示例xml

    <update id="updateUser">
        update test_user set test_user.u_name = (#{updateUserName}) where test_user.u_name = (#{userName})
    </update>

示例代码

        for (int i = 1; i <= num; i++) {
            User user = new User();
            user.setUserName("a" + i);
            user.setUpdateUserName("b" + i);
            userDao.updateUser(user);
        }

2.2 jdbc 批量更新

示例代码

Connection conn;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://192.168.0.200:3306/xxx", "root", "root");
            conn.setAutoCommit(false);

            // 保存当前自动提交模式
            boolean autoCommit = conn.getAutoCommit();
            // 关闭自动提交
            conn.setAutoCommit(false);
             Statement stmt =conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); 

            for (int i = 1; i <= num; i++) {
                stmt.addBatch("update test_user set test_user.u_name = ('d"+i+"') where test_user.u_name = ('c"+i+"')"); 
            }

            stmt.executeBatch();   
            conn.commit(); 
            conn.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

2.3 mybatis 批量更新

其实是利用了mysql的批量更新的语法
case when的语法
详见 【case when 语法
示例xml

    <update id="batchUpdateList">
        update test_user
        <trim prefix="set" suffixOverrides=",">

            <trim prefix="u_name =case" suffix="end,">
                <foreach item="item" collection="userList">
                    when test_user.u_name = (#{item.userName})
                    then #{item.updateUserName}
                </foreach>
            </trim>

        </trim>
        where
        <foreach item="item" collection="userList" separator="or">
            (test_user.u_name = (#{item.userName}))
        </foreach>

    </update>

示例代码

        for (int i = 1; i <= num; i++) {
            User user = new User();
            user.setUserName("a" + i);
            user.setUpdateUserName("b" + i);
            userList.add(user);
        }
        userDao.batchUpdateList(userList);

数据量分别是10,100,300,1000,5000条数据


数据量:10
批量更新耗时:279
非批量更新耗时:1522
jdbc批量更新耗时:255

数据量:100
批量更新耗时:720
非批量更新耗时:3391
jdbc批量更新耗时:1912

数据量:300
批量更新耗时:987
非批量更新耗时:9827
jdbc批量更新耗时:7616

数据量:500
批量更新耗时:1649
非批量更新耗时:16253
jdbc批量更新耗时:10475

数据量:1000
批量更新耗时:2552
非批量更新耗时:33048
jdbc批量更新耗时:20793

数据量:5000
批量更新耗时:19066
非批量更新耗时:239127
jdbc批量更新耗时:103273


这里写图片描述

综上分析,效率排比如下
mybatis批量更新 > jdbc批量更新 > 循环调用update语句

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炼丹狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值