使用JDBC进行批处理

 

使用JDBC进行批处理

1、业务场景:当需要向数据库发送一批SQL语句执行时,应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率。

2、实现批处理有两种方式。

(1)第一种方式:Statement.addBatch(sql)  (Statement中有一个集合属性list存储所有的sql),执行批处理SQL语句
executeBatch()方法:执行批处理命令
clearBatch()方法:清除批处理命令

案例3,批处理。

准备:

(2)com.hbsi.utils包下的DBManager类负责获得连接以及资源的释放。

(3)属性文件db.properties保存了建立连接时需要的参数。
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/demodb
username=root
password=root

(4)MySQL的驱动

(5)创建表
create table testbatch
(
    id int primary key,
    name varchar(100)
) ;

代码编写:Demo3.java

public void test1() {

           Connection conn = null;

           Statement st = null;

           ResultSet rs = null;

           try{

                  conn = DBManager.getConnection();

                  String sql1 = "insert into testbatch(id,name) values(1,'aa')";

                  String sql2 = "insert into testbatch(id,name) values(2,'bb')";

                  String sql3 = "delete from testbatch where id=1";

                 

                  st = conn.createStatement();

                  st.addBatch(sql1);//把sql语句加入到批中

                  st.addBatch(sql2);

                  st.addBatch(sql3);

                 

//该方法返回值为int[],返回的是每条sql语句执行后对表中记录的影响行数

                  st.executeBatch();                

st.clearBatch();

           }catch (Exception e) {

                  throw new RuntimeException(e);

           }finally{

                  DBManager.release(conn, st, rs);

           }

    }

3、采用Statement.addBatch(sql)方式实现批处理的优点:可以向数据库发送多条不同的SQL语句。缺点一是SQL语句没有预编译,二是当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句。例如:

              Insert into user(name,password) values(‘aa’,’111’);

              Insert into user(name,password) values(‘bb’,’222’);

              Insert into user(name,password) values(‘cc’,’333’);

              Insert into user(name,password) values(‘dd’,’444’);

4、  实现批处理的第二种方式:PreparedStatement.addBatch()

案例4,向数据库的表中插入1亿条记录。

public void test2() {

        long starttime = System.currentTimeMillis();

        Connection conn = null;

        PreparedStatement st = null; //list

        ResultSet rs = null;

        try{

               conn = DBManager.getConnection();

               String sql = "insert into testbatch(id,name) values(?,?)";

               st = conn.prepareStatement(sql);

              

               for(int i=0;i<10000004;i++){

                      st.setInt(1, i);

                      st.setString(2, "aa" + i);

                     

                      st.addBatch();

                      if(i%1000==0){

                             st.executeBatch();

                             st.clearBatch();

                      }

               }

               st.executeBatch();//为了保证最后那4条sql语句也会被提交

        }catch (Exception e) {

               throw new RuntimeException(e);

        }finally{

               DBManager.release(conn, st, rs);

        }

        long endtime = System.currentTimeMillis();

        System.out.println("共花了: " + (endtime-starttime)/1000 + "秒");

}

代码段:conn = DBManager.getConnection();

               String sql = "insert into testbatch(id,name) values(?,?)";

               st = conn.prepareStatement(sql);//预编译一下sql语句

st.setInt(1, 1);

               st.setString(2, "aa");

               //写到这在st中就有一条完整的sql语句了,因此可以加入批中

               st.addBatch();

       我们可以将上面的三条语句加入循环中即可向st中添加多条sql语句,所以我们可以写一个循环,循环1亿次,添加1亿条记录。即:

for(int i=0;i<10000000;i++){

                      st.setInt(1, i);

                      st.setString(2, "aa" + i);

                      st.addBatch();

               }

这样写完后执行,发现数据库的表中并没有我们想象的1亿条记录。为什么呢?

st语句对象中有一个list对象保存加入的sql语句,每条sql语句是要占一定内存的(8~9个字节),当你加1亿条sql语句时会占多少内存?内存一下就崩溃了。因此千万不要直接把这一亿条sql语句都加入到批中,使用如下的代码:

for(int i=0;i<10000000;i++){

        st.setInt(1, i);

        st.setString(2, "aa" + i);

                     

        st.addBatch();

        if(i%1000==0){//把1000条记录做成一批

               st.executeBatch();//提交给mysql去执行

               st.clearBatch();//提交后,要把批中的sql语句清掉

        }

}

这样还有问题:如果是循环1千万零4次,那最后的4条sql语句会提交给MySQL执行吗?不会!因此在该循环结束后还要有一条st.executeBatch()语句的执行。

这个程序写完后运行时花费的时间会很长,差不多3-4个小时。而在oracle下会很快,几分钟吧。

5、  采用PreparedStatement.addBatch()实现批处理

a)         优点:发送的是预编译后的SQL语句,执行效率高。

b)        缺点:只能应用在SQL语句相同,但参数不同的批处理中。因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据。

 

使用JDBC批处理操作需要以下步骤: 1. 创建一个Connection对象,连接到数据库。 2. 创建一个Statement对象,用于执行SQL语句。 3. 将多个SQL语句添加到批处理中,使用addBatch方法。 4. 执行批处理使用executeBatch方法。 5. 关闭Statement对象和Connection对象。 下面是一个简单的示例代码,展示如何使用JDBC批处理操作: ```java // 创建Connection对象 Connection conn = DriverManager.getConnection(url, username, password); // 创建Statement对象 Statement stmt = conn.createStatement(); // 添加多个SQL语句到批处理中 stmt.addBatch("INSERT INTO users (id, name) VALUES (1, 'Alice')"); stmt.addBatch("INSERT INTO users (id, name) VALUES (2, 'Bob')"); stmt.addBatch("INSERT INTO users (id, name) VALUES (3, 'Charlie')"); // 执行批处理 int[] results = stmt.executeBatch(); // 关闭Statement对象和Connection对象 stmt.close(); conn.close(); ``` 在上面的示例代码中,我们首先创建了一个Connection对象,连接到数据库。然后创建了一个Statement对象,将多个SQL语句添加到批处理中。最后执行批处理使用executeBatch方法。在执行完批处理之后,我们关闭了Statement对象和Connection对象。 需要注意的是,JDBC批处理操作一般适用于需要处理大量数据的情况,对于小批量数据的处理,使用单条SQL语句执行会更加高效。同时,在使用JDBC批处理操作时,需要注意数据库的限制和性能,以确保数据处理的效率和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值