什么是批处理?

什么是批处理?

  • 当需要向数据库中插入大批量数据时,在批处理之前,要执行100条sql,就只需100此打开连接关闭连接和网络传输。
  • 批处理过程:将大量的SQL打包成一个批次,发送给服务器,服务器接收数据,打开批,一次执行批里的sql,这样减少与数据库的交互,提高程序的效率。

- 如何实现批处理?

实现方式一:Statement对象实现
需求:利用statement开发,插入dept表,100条
实现方式二:Preparedstatement对象实现
需求:利用preparedstatement对象,向dept表中插入100条数据

开发步骤:

  • 1.获取数据库连接
  • 2.获取传输器
  • 3.执行SQL(批处理,打成一个批次,统一发给服务器)
  • 4.解析结果集
  • 5.关闭资源
    注意:每次利用批处理完成插入100条数据,打一个批次是,要统一发送数据

事务优化

需求:让批处理程序快一点
设置事务的开关:conn.setAutoCommit(false);
手动提交事务:conn.commit();

两种方式的区别:

  1. Statement
    *  优点:在一次批处理中,SQL更加灵活
    *   缺点:发生SQL注入,效率低,拼接参数麻烦
  2. preparedstatement
    * 优点:防止SQL注入,提高执行效率(骨架缓存),占位符拼接参数
    * 缺点:在一次批处理中,只可以完成骨架相同的SQL
  3. 总结:
    **  在没使用批处理时,插入100条SQL的话,需要打开100次数据库连接并且需要100次网络传输。
    **  使用了批处理,效率不一定就高,跟数据库的版本,驱动的版本,硬件配置,网络速度都有关系
    ** 使用jdbc批处理时建议结合着事务优化一起做
    **  注意:不建议一次性向批中插入大量数据,会造成OutofMemory

代码实现如下:

package on.tedu.batch_批处理;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.junit.Test;

import on.tedu.Util_工具类.JDBCUtils;

/**
 * 这个类用来完成批处理
 * 开发步骤:
 * 1.获取数据库连接
 * 2.获取传输器
 * 3.执行SQL(批处理,打成一个批次,统一发给服务器)
 * 4.解析结果集
 * 5.关闭资源
 * 两种方式的区别
 * 1.Statement
 * 优点:在一次批处理中,SQL更加灵活
 * 缺点:发生SQL注入,效率低,拼接参数麻烦
 * 
 * 2.perparedstatement
 * 优点:防止SQL注入,提高执行效率(骨架缓存),占位符拼接参数
 * 缺点:在一处批处理中,只可以完成骨架相同的SQL
 * 总结:
 * 在没使用批处理时,插入100条SQL的话,需要打开100此数据库连接并且需要100此网络传输
 * 使用了批处理,效率不一定就高,跟数据库的版本,驱动的版本,硬件配置,网络速度都有关系
 * 使用jdbc批处理时建议结合着事务处理优化一起做
 * 注意:不建议一次性向批中插入大量数据,会造成OutofMenory
 * @date 2018年3月26日
 *
 */
public class StatementBatch {

    @Test//单元测试
    public void statementBatch(){
        Connection conn = null;
        Statement st =null;
        ResultSet rs =null;
        try {
            //1.获取数据库连接
            conn = JDBCUtils.getConnection();
            //2.获取传输器对象
            st=conn.createStatement();
            //3.执行SQL(批处理,打成一个批次,统一发给服务器)   
            int rows=0;
            for(int i=0;i<100;i++){
                //普通插入100条数据的方法
                //rows =st.executeUpdate("insert into dept values(null,'"+i+"')");
                //利用批处理完成插入100条数据
                //并打一个批次
                st.addBatch("insert into dept values(null,'"+i+"')");
            }
            //统一把SQL发送给服务器
            st.executeBatch();
            System.out.println(rows);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            JDBCUtils.close(conn, st, rs);
        }
    }
    @Test//插入数据 最终版
    public void PSBatch(){
        Connection conn=null;
        PreparedStatement ps =null;

        try {
            //1.获取数据库连接
            conn =JDBCUtils.getConnection();
            //设置数据的开关 - 把默认事务关闭 --非常关键
            conn.setAutoCommit(false);
            long start =System.currentTimeMillis();
            //2.获取传输器对象
            //3.执行SQL
            String sql ="insert into dept values(null,?)";
            ps=conn.prepareStatement(sql);//传入骨架
            //设置参数
            for(int i=0;i<100;i++){
                ps.setString(1, "ps"+i);//这里的i代表的是一个?号
                //把SQL添加到一个批次中
                ps.addBatch();//这里添加到批次里
            }
            //统一把SQL发给服务器
            int[] rows = ps.executeBatch();//这里返回一个int[],意识是影响了一行,就会得到一个数字
            //手动提交事务
            conn.commit();
            long end = System.currentTimeMillis();
            System.out.println(rows.length);
            System.out.println("-----------"+(end-start)+"-----------");
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            //5关闭资源,这里直接传子类对象,后面rs没有,就直接传null
            JDBCUtils.close(conn, ps, null);
        }

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章