JDBC批处理的实现

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

实现批处理有两种方式,第一种方式:如果有100条sql语句,调用addBatch(sql)方法时,就会把sql语句加到list集合里去

Statement.addBatch(sql) list

执行批处理SQL语句:

executeBatch()方法:执行批处理命令
clearBatch()方法:清除批处理命令

练习

连接数据库的代码我就不细述了,前面文章里都有。

 @Test
    public void test1() {
        Connection conn = null;
        //用Statement去做
        Statement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql1 = "insert into testbatch(id,name) values('1','aaa')";
            String sql2 = "update testbatch set name='bbb' where id='1'";
            st = conn.createStatement();
            st.addBatch(sql1);
            st.addBatch(sql2);

            //返回int[] 第一条sql影响数据库几行,第二条sql影响数据库几行
            st.executeBatch();
            //发给数据库之后,就要清理批处理
            st.clearBatch();

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtils.release(conn, st, rs);
        }
    }

结果就是将id为1的name更改为了bbb

第二种方式:

用PreparedStatement 语句时只能向数据库发送一条sql语句,只是可以做批量数据的处理。而第一种方式可以发送不同的sql语句。

实际开发里,这种方式用的比较多。

 @Test
    public void test2() {
        Connection conn = null;
        //用Statement去做
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "insert into testbatch(id,name) values(?,?)";
            ps = conn.prepareStatement(sql);

            /*
            //1
            ps.setString(1,"2");
            ps.setString(2,"qwer");
            ps.addBatch();

            //2
            ps.setString(1,"3");
            ps.setString(2,"asdf");
            ps.addBatch();
            */

            //换用for循环实现
            for (int i = 1; i <= 10; i++) {
                ps.setString(1, i + "");
                ps.setString(2, "aa" + i);
                ps.addBatch();
            }
            //返回int[] 第一条sql影响数据库几行,第二条sql影响数据库几行
            ps.executeBatch();
            //发给数据库之后,就要清理批处理
            ps.clearBatch();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtils.release(conn, ps, rs);
        }
    }

注意:如果for循环里的i<=10000000,就意味着一次性要插入1000万条数据,会报java.lang.OutOfMemoryError:Java heap space,超出内存空间。所以1000万条数据就不能这样插入,而是采取1000条1000条的插入(每1000条做一个批处理)。改动后的代码如下:

 @Test
    public void test2() {
        Connection conn = null;
        //用Statement去做
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "insert into testbatch(id,name) values(?,?)";
            ps = conn.prepareStatement(sql);

            //换用for循环实现
            for (int i = 1; i <= 10; i++) {
                ps.setString(1, i + "");
                ps.setString(2, "aa" + i);
                ps.addBatch();

                if (i % 1000 == 0) {
                    //返回int[] 第一条sql影响数据库几行,第二条sql影响数据库几行
                    ps.executeBatch();
                    //发给数据库之后,就要清理批处理
                    ps.clearBatch();
                }
            }
            ps.executeBatch();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtils.release(conn, ps, rs);
        }
    }

MySQL插入1000万条数据大概要3个多小时。oracle就只需要6分多钟。

你可能感兴趣的:(JDBC批处理的实现)