DRP——JDBC中的Batch

本文探讨了在JDBC中使用批量处理(batch)功能,通过将多个SQL语句作为一个单元发送至数据库执行,以提高大量数据操作的效率。与逐条执行相比,批量处理能显著减少数据库调用次数,提升性能。通过实例展示了如何在Java中实现批量插入,并与传统的单条执行方式进行了对比,揭示了批量处理在实际应用中的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      在jdbc2.0里增加了批量处理的功能(batch),其允许将多个sql语句作为一个单元送至数据库去执行,这样做可以提高操作效率。在操作大量的数据时, ORM框架实现批量是很慢的。我们可以使用jdbc提供的Batch来提高效率。

示例:

首先是使用for循环,一句一句的执行:

public class TestCommon {
	static long startTime;
	public static void main(String[] args) throws Exception {  
		
        Connection conn = getConnection();  
        PreparedStatement ps = null;  
        try {  
        	startTime=System.nanoTime();   //获取开始时间 
            ps = conn  
                    .prepareStatement("INSERT INTO batchtab  values (?, ?)");    
            conn.setAutoCommit(false);              
            for (int n = 0; n < 10000; n++) {  
                Integer i = new Integer(n);  
                ps.setString(1, i.toString());  
                ps.setString(2, "value" + i.toString());  
                ps.executeUpdate();  
            }  
            conn.commit();
            long endTime=System.nanoTime(); //获取结束时间
            System.out.println("程序运行时间: "+(endTime-startTime)+"ns"); 
        }catch (SQLException ex) {  
            System.out.println("SQLException: " + ex.getMessage());  
            System.out.println("SQLState: " + ex.getSQLState());  
            System.out.println("Message: " + ex.getMessage());  
            System.out.println("Vendor error code: " + ex.getErrorCode());  
        } catch (Exception e) {  
            e.printStackTrace();  
            System.err.println("Exception: " + e.getMessage());  
        } finally {  
            if (conn != null)  
                conn.close();  
            if (ps != null)  
                ps.close();        
        }  
    }  
  

    
    public static Connection getConnection() {  
    	  Connection con = null;  //创建用于连接数据库的Connection对象  
          try {  
              Class.forName("com.mysql.jdbc.Driver");// 加载Mysql数据驱动  
                
              con = DriverManager.getConnection(  
                      "jdbc:mysql://localhost:3306/TestBatch", "root", "123456");// 创建数据连接  
                
          } catch (Exception e) {  
              System.out.println("数据库连接失败" + e.getMessage());  
          }  
          return con; //返回所建立的数据库连接  
    }  
}  

使用Batch,批量操作:

public class TestPreStatementBatch {
	static long startTime;
	public static void main(String[] args) throws Exception {  
		
        Connection conn = getConnection();  
        ResultSet rs = null;  
        PreparedStatement ps=null;  
        try {  
  
        	 startTime=System.nanoTime();   //获取开始时间  
             
            ps = conn.prepareStatement("INSERT INTO batchtab values (?, ?)");  
            conn.setAutoCommit(false);  
            ps.clearBatch();  
 
            for (int n=0; n<10000; n++) { 
            	Integer i = new Integer(n); 
                ps.setString(1, i.toString());  
                ps.setString(2, "value" + i.toString());  
                ps.addBatch();  
            }  
            ps.executeBatch();  
            conn.commit();  
            long endTime=System.nanoTime(); //获取结束时间
            //打印消耗时间
            System.out.println("程序运行时间: "+(endTime-startTime)+"ns");  
        } catch (BatchUpdateException b) {  
            System.out.println("SQLException: " + b.getMessage());  
            System.out.println("SQLState: " + b.getSQLState());  
            System.out.println("Message: " + b.getMessage());  
            System.out.println("Vendor error code: " + b.getErrorCode());  
            System.out.print("Update counts: ");  
           
        } catch (SQLException ex) {  
            System.out.println("SQLException: " + ex.getMessage());  
            System.out.println("SQLState: " + ex.getSQLState());  
            System.out.println("Message: " + ex.getMessage());  
            System.out.println("Vendor error code: " + ex.getErrorCode());  
        } catch (Exception e) {  
            e.printStackTrace();  
            System.err.println("Exception: " + e.getMessage());  
        } finally {  
            if( conn != null )  
            conn.close();  
         if(ps !=null)  
            ps.close();  
            if(rs !=null)  
            rs.close();   
            
        }  
    }  
  
	public static Connection getConnection() {  
  	  Connection con = null;  //创建用于连接数据库的Connection对象  
        try {  
            Class.forName("com.mysql.jdbc.Driver");// 加载Mysql数据驱动  
              
            con = DriverManager.getConnection(  
                    "jdbc:mysql://localhost:3306/TestBatch", "root", "123456");// 创建数据连接  
              
        } catch (Exception e) {  
            System.out.println("数据库连接失败" + e.getMessage());  
        }  
        return con; //返回所建立的数据库连接  
  }  	
}

不同点:


 

    

         一条条的循环插入是每插入一条数据都会调用一次执行;而Batch是把所有的数据全都存起来,之后调用一次执行。数据量很大的话,效率就会差很多。

 

数据说话——运行结果:

 



 

总结: 

         通过插入一万条一样的数据消耗的时间,我们可以看到相差的时间。我们可以通过减少语句的多次执行来提高性能。其实,同.NET中的SqlBulkCopy思想一样,一次执行WriteToServer。就如同生活中我们做事情一样,不能只想做了就行,还要多多思考有没有什么方法可以做到更好。


评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值