DRP——JDBC中的Batch

在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。就如同生活中我们做事情一样。不能仅仅想做了即可,还要多多思考有没有什么方法能够做到更好。

时间: 2024-12-23 12:40:01

DRP——JDBC中的Batch的相关文章

在JDBC中使用带参数的SQL语句

ADO.Net中,支持带参数的SQL语句,例如:Select * from Tables where [email protected],其中@column1为SQL参数,使用起来非常方便,而JDBC中没有找到此功能,感觉有点不便, 于是想自己实现一个.今天正好看见csdn中有一篇http://blog.csdn.net/wallimn/article/details/3734242 文章,有些感触,于是把自己的实现也写出来. 我的思路: 1: 在SQL语句中找到以@开始,以" ",

JDBC中PreparedStatement接口提供的execute、executeQuery和executeUpdate之间的区别及用法

JDBC中PreparedStatement接口提供的execute.executeQuery和executeUpdate之间的区别及用法 (2012-08-27 09:36:18) 转载▼ 标签: statement execute executequery executeupdate 杂谈 分类: DataBase区 PreparedStatement接口提供了三种执行 SQL 语句的方法:executeQuery.executeUpdate 和 execute.使用哪一个方法由 SQL 语

JDBC中常用对象介绍

JDBC中的主要类(接口) 在JDBC中常用的类有: 1.DriverManager 2.Connection 3.Statement 4.ResultSet 1.DriverManager 其实我们今后只需要会用DriverManager的getConnection( )方法即可: 1. Class.forName("com.mysql.jdbc.Driver");//注册驱动 2. String url = "jdbc:mysq  l://localhost:3306/m

开发PL/SQL子程序和包及使用PL/SQL编写触发器、在JDBC中应用Oracle

1.  子程序的各个部分: 声明部分.可执行部分.异常处理部分(可选) 2.子程序的分类: A.  过程 - 执行某些操作 a.  创建过程的语法: CREATE [OR REPLACE]  PROCEDURE  <procedure name> [(<parameter list>)]  IS|AS <local variable declaration> BEGIN <executable statements> [EXCEPTION <excep

DRP学习中的模型进化

以前做系统是按照三层的思想来做的,即U ,B ,D .坐着坐着,开始不断加入设计模式,加入sqlhelper ,渐渐的知道了系统不只可以分三层,原来是可以分很多层的,随着学习的不断深入明白了"为什么会出现分层".知道了是一回事,关键还是在"怎么用",所以我们还在为"分层"而进行不懈的努力着-- 现在学习到了DRP,又认识了一个分层:MVC(model-view-control). 正式语言这么描述:用一种业务逻辑.数据.界面显示分离的方法组织代码

JDBC中的事务-Transaction

事务-Transaction 某些情况下我们希望对数据库的某一操作要么整体成功,要么整体失败,经典的例子就是支付宝提现.例如我们发起了支付宝到银行卡的100元提现申请,我们希望的结果是支付宝余额减少100元,银行卡余额增加100元,而不是支付宝的100元被扣除,而银行卡的100元却没收到.也就是说,要么100元从支付宝扣除的同时银行卡也会多出一百元,要么这次提现失败支付宝的100元还在,银行卡也没有收到钱.支付宝扣钱和银行卡收钱,这两件事要么都成功要么都失败. 事物的ACID特性: 满足ACID

jdbc中PreparedStatement中in的用法

jdbc中sql不支持IN直接传入字符串,例如'0001','0002'等这样子的方法,所以需要根据传入参数的个数来构造?的个数 例如传入为一个数组或一个list  String[]{'0001','0002'} 那么构造的in 就为 in(?,?) 相对应的for循环数组长度来传入参数 for(in t index=0;index<xx.length;index++){ ps.setString(index,xx[index]); } 通过动态的构造sql语句和动态传值就能够实现类似于myba

使用JDBC中的出现的乱码和查询无结果问题

使用JDBC中的问题 连接的后出现查询结果是乱码. 1.可能是代码的编码与数据库的编码不同 ? 有可以将二者都设置为UTF-8 2.如果比较懒得话可以只设代码为UTF-8 mysql 连接url中useUnicode=true&characterEncoding=UTF-8 的作用 添加的作用是:指定字符的编码.解码格式. ? 例如:mysql数据库用的是gbk编码,而项目数据库用的是utf-8编码.这时候如果添加了useUnicode=true&characterEncoding=UTF

jdbc中对mysql数据库操作的简单封装--(仅做备忘记录)

本次使用jdbc中的mysql-connector-java-5.1.47-bin.jar的连接包,下载这个jar包放在javaee项目的WEB-INF/lib目录下,再把它作为外包jar包进入到libraries中,这样就可以使用mysql的jdbc接口了. 自己封装的代码中引入了两个自己字义的Exception:SqlSecureException.java package com.myproweb.exception; public class SqlSecureException ext