• 【JDBC】事务,批处理


    1.JDBC事务概述

    开启事务的关键代码是conn.setAutoCommit(false),表示关闭自动提交。提交事务的代码在执行完指定的若干条SQL语句后,调用conn.commit()。要注意事务不是总能成功,如果事务提交失败,会抛出SQL异常(也可能在执行SQL语句的时候就抛出了),此时我们必须捕获并调用conn.rollback()回滚事务。最后,在finally中通过conn.setAutoCommit(true)把Connection对象的状态恢复到初始值。

    实际上,默认情况下,我们获取到Connection连接后,总是处于“自动提交”模式,也就是每执行一条SQL都是作为事务自动执行的,这也是为什么前面几节我们的更新操作总能成功的原因:因为默认有这种“隐式事务”。只要关闭了Connection的autoCommit,那么就可以在一个事务中执行多条语句,事务以commit()方法结束。


    2.JDBC事务的使用方案

    JDBC事务使用案例:

    /**
     * JDBC事务演示
     */
    public class JdbcAffairs {
        public static void main(String[] args) {
            Connection connection = null;
            PreparedStatement preparedStatement = null;
            String sql = "update user set school = '东南大学' where id = 1";
            String sql2 = "update user set school = '河海大学' where id = 2";
            try {
                connection = JdbcUtils.getConnection();
                // 将connection设置为不自动提交事务
                connection.setAutoCommit(false);
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.executeUpdate();
                PreparedStatement preparedStatement1 = connection.prepareStatement(sql2);
                preparedStatement1.executeUpdate();
                // 提交事务
                connection.commit();
            } catch (SQLException e) {
                // 进行回滚
                try {
                    // 默认回滚到事务开始的状态
                    connection.rollback();
                } catch (SQLException ex) {
                    throw new RuntimeException(ex);
                }
                throw new RuntimeException(e);
            } finally {
                // 关闭连接
                JdbcUtils.close(null, preparedStatement, connection);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    3.批处理

    多条sql语句统一提交数据库执行,这会使效率更高

    普通方式使用for循环批量添加数据(效率低❌):

    Connection connection = JdbcUtils.getConnection();
    String sql = "insert into user values (?,?,?,?)";
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    for (int i = 0; i < 50; i++) {
        preparedStatement.setInt(1, i + 7);
        preparedStatement.setString(2, "qy" + i);
        preparedStatement.setString(3, "adminadmin" + i);
        preparedStatement.setString(4, "中国大学" + i);
        preparedStatement.executeUpdate();
    }
    JdbcUtils.close(null, preparedStatement, connection);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    使用JDBC批处理机制添加数据(效率高√ 【减少发送sql语句的网络开销,减少编译次数】):

    注意:使用JDBC批处理时,连接数据库的url请务必加入此参数:

    rewriteBatchedStatements=true
    
    • 1

    可以使用executeBatch,执行当前批量更新缓存中的所有命令。返回一个记录数的数组,其中每一个元素都对应一条语句,如果其值非负,则表示受该语句影响的记录总数;如果其值为SUCCESS_NO_INFO,则表示该语句成功执行了,但没有记录数可用;如果其值为EXECUTE_FAILED,则表示该语句执行失败了

    示例代码:

    /**
     * JDBC批处理演示
     * @throws Exception
     */
    @Test
    public void batchProcessingMethod() throws Exception {
        Connection connection = JdbcUtils.getConnection();
        String sql = "insert into user values (?,?,?,?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < 50; i++) {
            preparedStatement.setInt(1, i + 107);
            preparedStatement.setString(2, "qyee" + i);
            preparedStatement.setString(3, "ppp" + i);
            preparedStatement.setString(4, "北京大学" + i);
            // 将sql语句加入到批处理中
            preparedStatement.addBatch();
            // 当存在10条数据时,批量处理执行
            if ((i + 1) % 10 == 0) {
                preparedStatement.executeBatch();
                // 清空数据继续待添加
                preparedStatement.clearBatch();
            }
        }
        JdbcUtils.close(null, preparedStatement, connection);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    使用 Netty 实现简易版 Dubbo RPC 远程调用过程
    激光雷达与自动驾驶详解
    ES6:数值的扩展
    八、自定义映射resultMap
    消息队列-RabbitMQ(二)
    鼠标点击选取物体错误的问题
    线程的状态简介说明
    Windows------openvino 2022.1安装步骤
    异常数据检测 | Python奇异谱分析(SSA)数据缺失值插补
    Linux学习-69-Linux系统启动管理
  • 原文地址:https://blog.csdn.net/Gherbirthday0916/article/details/126445821