jdbc批量处理

2012/04/12 2257点热度 0人点赞 0条评论

注:mysql不支持jdbc的批量处理

在增删改多条数据的时候,一条条的循环操作会一直不断的向数据库要连接,效率低下.而是用批量处理的话,执行多条sql语句只需要是用一次数据库连接就能完成.

JDBC给我们提供了批量处理的接口,主要是三个方法:

//将给定的ql命令添加到此statement对象的列表中

      stmt.addBatch(sql);

//将一批sql命令提交给数据库执行,如果执行成功,则返回更成功的数组

      stmt.executeBatch();

//清空statement对象的当前sql

      stmt.clearBatch();

案例:

@TEST
//这种情况适用于多条sql语句
public  void testStatment {
    Connection conn=null;
    Statement stmt=null;
    try {
        String sql="";
        conn=JDBCUtils.getConnection();
        //统计使用时间,开始时间
        Long beginTime=System.currentTimeMillis();
                                           
        stmt=conn.createStatement();
        for(int i=1;i<=5000;i++){
            String name="tom"+i;
            String email="email"+i;
            sql="INSERT INTO emp(id,name,email) VALUES("+i+",'"+name+"','"+email+"')";
                               
            //将给定的 SQL 命令添加到此 Statement 对象的当前命令列表中(集合中)
            stmt.addBatch(sql);
            //每500条一提交
            if(i%500==0){
                //将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。
                stmt.executeBatch();
                //清空此 Statement 对象的当前 SQL 命令列表。
                stmt.clearBatch();
            }
        }
@TEST
//这种情况适用于一条sql语句多的批量传参
public void testPreparedStatment {
    Connection conn=null;
    PreparedStatement pstmt=null;
    try {
        conn=JDBCUtils.getConnection();
                          
        String sql="INSERT INTO emp(id,name,email) VALUES(?,?,?)";
        Long beginTime=System.currentTimeMillis();
                                      
        pstmt=conn.prepareStatement(sql);
        for(int i=1;i<=100000;i++){
            //设置参数的值
            pstmt.setInt(1, i);
            pstmt.setString(2, "tom"+i);
            pstmt.setString(3, "email"+i);
                                          
            //将给定的 SQL 命令添加到此 PreparedStatement 对象的当前命令列表中(集合中)
            pstmt.addBatch();
                                          
            if(i%1000==0){
                //将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。
                pstmt.executeBatch();
                //清空此 PreparedStatement 对象的当前 SQL 命令列表。
                pstmt.clearBatch();
            }
        }   
        Long endTime=System.currentTimeMillis();
        System.out.println(endTime-beginTime+"毫秒");          
    } catch (SQLException e) {
        e.printStackTrace();
    }finally{
        JDBCUtils.closeResource(conn, pstmt, null);
    }
}
        Long endTime=System.currentTimeMillis();
        System.out.println((endTime-beginTime)/1000+"秒");
                                           
    } catch (SQLException e) {
        e.printStackTrace();
    }finally{
        JDBCUtils.closeResource(conn, stmt, null);
    }
}

工具类JDBCUtils.java

public class JDBCUtils {
                        
    private static String url = "jdbc:oracle:thin:@localhost:1521:orcl";
    private static String username = "scott";
    private static String password = "tiger";
    private static String driverClassName = "oracle.jdbc.driver.OracleDriver";
                        
    static {
        try {
            Class.forName(driverClassName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
                        
    public static Connection getConnection() {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url, username, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if (conn == null) {
            throw new RuntimeException("获取连接失败");
        }
        return conn;
    }
                        
    public static void closeResource(Connection conn, Statement stmt,ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            rs=null;
            e.printStackTrace();
        }finally{
            try {
                if(stmt!=null){
                    stmt.close();
                }
            } catch (SQLException e) {
                stmt=null;
                e.printStackTrace();
            }finally{
                try {
                    if(conn!=null){
                        conn.close();
                    }
                } catch (SQLException e) {
                    conn=null
                    e.printStackTrace();
                }
            }
        }
    }
}

注意:

1 .testStatment 不可以添加查询SQL,因为executeBatch()返回的是int [],如果把返回ResultSet的SQl加入会引起异常;
2 .testPreparedStatment可以适用于没有返回参数的存储过程,如果存储过程有返回参数,是不可以使用批量处理的!

3.如果批量执行的数量<50的话,和平常没什么区别

yxkong

这个人很懒,什么都没留下

文章评论