JDBC学习(七) --- 批处理

批处理

 批处理是指你将关联的 SQL 语句组合成一个批处理,并将他们当成一个调用提交给数据库。当你一次发送多个 SQL 语句到数据库时,批处理可以减少通信的资源消耗,从而提高了性能

 对于 JDBC 的批处理,有以下几点需要进行说明:

  • Statement,PreparedStatement 和 CallableStatement 的 addBatch() 方法用于添加单个语句到批处理。
  • executeBatch() 方法用于启动执行所有组合在一起的语句。
  • executeBatch() 方法返回一个整数数组,数组中的每个元素代表了各自的更新语句的更新数目。
  • 你不仅可以添加语句到批处理,还可以用 clearBatch() 方法删除它们。此方法删除所有用 addBatch()方法添加的语句。但你不能选择性的对语句进行删除。

批处理操作流程

Statement 对象

  • 使用 createStatement()方法创建一个 Statement 对象;
  • 使用 setAutoCommit()方法将自动提交设置为 false;
  • 使用 Statement 对象的 addBatch()方法添加你需要执行的一系列 SQL 语句;
  • 使用 Statement 对象的 executeBatch()方法执行所有的 SQL 语句;
  • 使用 commit()方法提交所有的更改。

 示例如下:

Statement stmt = conn.createStatement();
conn.setAutoCommit(false);

String SQL = "...";

stmt.addBatch(SQL);


String SQL = "...";

stmt.addBatch(SQL);


String SQL = "...";

stmt.addBatch(SQL);

conn.commit();

PrepareStatement 对象

  • 使用占位符创建 SQL 语句;
  • 创建 PrepareStatement 对象;
  • 使用 setAutoCommit()方法将自动提交设置为 false;
  • 使用被创建的 PrepareStatement 对象的 addBatch()方法来添加 SQL 语句;
  • 使用被创建的 PrepareStatement 对象的 executeBatch()方法将所有的 SQL 语句执行;
  • 使用 commit()方法提交所有更改。

 示例如下:

String SQL = "INSERT INTO Employees (id, first, last, age) " +
             "VALUES(?, ?, ?, ?)";
PreparedStatemen pstmt = conn.prepareStatement(SQL);

conn.setAutoCommit(false);


pstmt.setInt( 1, 400 );
pstmt.setString( 2, "Pappu" );
pstmt.setString( 3, "Singh" );
pstmt.setInt( 4, 33 );

pstmt.addBatch();

pstmt.setInt( 1, 401 );
pstmt.setString( 2, "Pawan" );
pstmt.setString( 3, "Singh" );
pstmt.setInt( 4, 31 );

pstmt.addBatch();

conn.commit();

练习

 我们分别用两种方式(一种非批处理,一种批处理)向 Order 表中插入 10000 条数据,观察两者所执行的时间。

 操作前 order 表的内容:

 表中只有 5 条数据(以自己的表为主),为了简单起见,我们插入的 id 要从 6 开始,同时,order_name 设为插入数据的序列号(从 0 开始)。

 为了便于操作,我们先用 JDBC 实现插入 10000 条数据后需要执行的删除操作:

@Test
public void deleteDateTest(){
    Connection conn = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    try {
        conn = JDBCUtils.getJDBCConnection();
        // 删除id大于5的信息
        // 注意:order在MySQL中是一个关键字,因此要用两个``将它标识出来
        String sql = "delete from `order` where `order_id` > 5";
        preparedStatement = conn.prepareStatement(sql);
        preparedStatement.execute();
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        try {
            JDBCUtils.closeResource(conn,preparedStatement,resultSet);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

 不使用批处理的代码:

@Test
public void insertTest(){
    Connection conn = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    try {
        conn = JDBCUtils.getJDBCConnection();
        String sql = "Insert into `order` (order_id,order_name) VALUES (?,?) ;";
        preparedStatement = conn.prepareStatement(sql);
        // 获取当前时间
        Date start = new Date();
        long start_time = start.getTime();
        // 循环插入100条数据
        for(int i=0;i<10000;i++){
            preparedStatement.setInt(1,5+i+1);
            preparedStatement.setString(2,"" + i);
            // 直接执行SQL
            preparedStatement.executeUpdate();
        }
        Date end = new Date();
        long end_time = end.getTime();
        System.out.println("执行时间:" + (end_time - start_time));
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        try {
            JDBCUtils.closeResource(conn,preparedStatement,resultSet);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

 运行结果:

执行时间:35343

 批处理执行的代码,执行前请执行下删除数据的操作:

 @Test
public void insertBatchTest(){
    Connection conn = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    try{
        conn = JDBCUtils.getJDBCConnection();
        conn.setAutoCommit(false);
        String sql = "insert into `order` (order_id, order_name) VALUES (?,?)";
        preparedStatement = conn.prepareStatement(sql);
        Date start_date = new Date();
        long start = start_date.getTime();
        for(int i=0;i<10000;i++){
            preparedStatement.setInt(1,6+i);
            preparedStatement.setString(2,""+i);
            preparedStatement.addBatch();
        }
        preparedStatement.executeBatch();
        conn.commit();
        Date end_date = new Date();
        long end = end_date.getTime();
        System.out.println("执行时间:" + (end - start));
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        try {
            conn.setAutoCommit(true);
            JDBCUtils.closeResource(conn,preparedStatement,resultSet);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

 运行结果:

执行时间:3836

 通过上述练习,可以看出在执行一些列 SQL 语句时,批处理操作能够极大的提高执行效率,因此,在处理需要一次性执行多条 SQL 语句时,批处理是非常好的一个选择。

上述完整代码

import org.junit.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Date;

/**
 * ClassName: JDBCBatchExample
 * Package: ning
 * Description:
 *
 * @Author: Ning
 */
public class JDBCBatchExample {

    @Test
    public void deleteDateTest(){
        Connection conn = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            conn = JDBCUtils.getJDBCConnection();
            String sql = "delete from `order` where `order_id` > 5";
            preparedStatement = conn.prepareStatement(sql);
            preparedStatement.execute();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                JDBCUtils.closeResource(conn,preparedStatement,resultSet);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Test
    public void insertTest(){
        Connection conn = null;
        PreparedStatement preparedStatement = null;
        try {
            conn = JDBCUtils.getJDBCConnection();
            String sql = "Insert into `order` (order_id,order_name) VALUES (?,?) ;";
            preparedStatement = conn.prepareStatement(sql);

            Date start = new Date();
            long start_time = start.getTime();
            // 循环插入100条数据
            for(int i=0;i<10000;i++){
                preparedStatement.setInt(1,5+i+1);
                preparedStatement.setString(2,"" + i);
                preparedStatement.executeUpdate();
            }
            Date end = new Date();
            long end_time = end.getTime();
            System.out.println("执行时间:" + (end_time - start_time));
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            ResultSet resultSet = null;
            try {
                JDBCUtils.closeResource(conn,preparedStatement,resultSet);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Test
    public void insertBatchTest(){
        Connection conn = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try{
            conn = JDBCUtils.getJDBCConnection();
            conn.setAutoCommit(false);
            String sql = "insert into `order` (order_id, order_name) VALUES (?,?)";
            preparedStatement = conn.prepareStatement(sql);
            Date start_date = new Date();
            long start = start_date.getTime();
            for(int i=0;i<10000;i++){
                preparedStatement.setInt(1,6+i);
                preparedStatement.setString(2,""+i);
                preparedStatement.addBatch();
            }
            preparedStatement.executeBatch();
            conn.commit();
            Date end_date = new Date();
            long end = end_date.getTime();
            System.out.println("执行时间:" + (end - start));

        }catch (Exception e){
            e.printStackTrace();
        }finally {

            try {
                conn.setAutoCommit(true);
                JDBCUtils.closeResource(conn,preparedStatement,resultSet);
            }catch (Exception e){
                e.printStackTrace();
            }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

PG Thinker

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

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

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

打赏作者

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

抵扣说明:

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

余额充值