首先分析一下批量插入的逻辑

//循环插入100,0000条记录
for (int i = 0; i < 1000000; i++) {
    //执行插入操作
    rowsInserted = pstmt.executeUpdate();
}
//输出计时

上述代码创建一个循环,循环一百万次,每一次循环更新插入一条数据,这样一来就是对数据库操作了一百万次,虽然实现了批量操作,但是却对数据库造成了很大的开销,如果数据量再进一步扩大,此方法保不齐会让服务崩掉,所以这不是个最优解。

能不能对数据库只操作一次,就能实现数据的批量操作呢?

事务

我可以开启一个事务,把一百万次的循环插入放到一个批处理中,最后提交事务,这样一来只对数据库进行一次操作实现数据批量插入。

接下来设计代码:

import java.sql.*;

public class SQLiteBatchInsert {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            //建立数据库连接
            Class.forName("org.sqlite.JDBC");
            conn = DriverManager.getConnection("jdbc:sqlite:D:\\env\\SQLite\\data\\user.db");
            //设置手动提交事务
            conn.setAutoCommit(false);
            String tableName = "user";
            // 准备SQL语句
            String sql = "INSERT INTO " + tableName + " (name, age) VALUES (?,?)";
            pstmt = conn.prepareStatement(sql);
            //批量添加数据
            for (int i = 0; i < 1000000; i++) {
                pstmt.setString(1, "王五");
                pstmt.setString(2, "25");
                pstmt.addBatch();
            }
            // 记录执行开始时间
            double startTime = System.currentTimeMillis();
            //执行批处理
            pstmt.executeBatch();
            //提交事务
            conn.commit();
            //记录执行结束时间
            double endTime = System.currentTimeMillis();
            double duration = endTime - startTime;
            System.out.println("Batch insert successful!");
            System.out.println("执行时间为:"+duration/1000+"s");
        } catch (SQLException | ClassNotFoundException e) {
            e.printStackTrace();
            if (conn != null) {
                try {
                    //如果出现异常,回滚事务
                    conn.rollback();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
        } finally {
            //关闭资源
            try {
                if (pstmt != null) pstmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

运行后发现,执行时间惊人的只有 1s 左右

SQLite利用事务实现批量插入(提升效率)-LMLPHP

为了验证这一结果,我不得不去数据库里查一下,果不其然插入成功

SQLite利用事务实现批量插入(提升效率)-LMLPHP

看来,SQLite 利用事务执行批量操作完全是个可行的方案,大大的降低了对数据库的开销,极大的减少了执行时间,效率有了质的提升。


05-13 05:58