注: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的话,和平常没什么区别
文章评论