JDBC 批量操作

来源:互联网 发布:java 代码生成器插件 编辑:程序博客网 时间:2024/06/06 01:49

批量删除:

DELETE FROM MyTable WHERE ID IN (1,2);

sql写法:

INSERT INTO TestTable SELECT
1,'abc' UNION SELECT 2,'bcd' UNION SELECT 3,'cde'
--TestTable表没有主键,ID不是主键

oracle写法:

INSERT INTO TestTable SELECT
1,'abc' From daul UNION SELECT 2,'bcd' From daul
--TestTable表没有主键,ID不是主键

但是要使用上述方法来进行批量插入的话,需要两个条件:

      1、表不能有主键或者主键是数据库默认的(sql用自动递增列,oracle用序列)

      2、组合sql语句时只能直接用字符串连接,不能用参数化sql语句的写法(就是在组合的sql中用@parm做占位符,再给Command对象添加Parameter)

    以上两条任意一条不满足,效率的提高都不明显。


INSERT INTO MyTable(ID,NAME) VALUES(7,'003'),(8,'004'),(9,'005');

JDBC批量插入主要用于数据导入和日志记录因为日志一般都是先写在文件下的等。 

我用Mysql 5.1.5的JDBC driver 分别对三种比较常用的方法做了测试 

  • 方法一,使用PreparedStatement加批量的方法
Java代码  收藏代码
  1.    
  2. try {  
  3.       Class.forName("com.mysql.jdbc.Driver");  
  4.       conn = DriverManager.getConnection(o_url, userName, password);  
  5.       conn.setAutoCommit(false);  
  6.       String sql = "INSERT adlogs(ip,website,yyyymmdd,hour,object_id) VALUES(?,?,?,?,?)";  
  7.       PreparedStatement prest = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);  
  8.       for(int x = 0; x < size; x++){  
  9.          prest.setString(1"192.168.1.1");  
  10.          prest.setString(2"localhost");  
  11.          prest.setString(3"20081009");  
  12.          prest.setInt(48);  
  13.          prest.setString(5"11111111");  
  14.          prest.addBatch();  
  15.       }  
  16.       prest.executeBatch();  
  17.       conn.commit();  
  18.       conn.close();  
  19. catch (SQLException ex) {  
  20.    Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null, ex);  
  21. catch (ClassNotFoundException ex) {  
  22.      Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null, ex);  
  23. }  

说明下在建Statement的时候,后面两个参数的意义: 
第一个参数指定 ResultSet 的类型。其选项有: 
TYPE_FORWARD_ONLY:缺省类型。只允许向前访问一次,并且不会受到其他用户对该数据库所作更改的影响。 
TYPE_SCROLL_INSENSITIVE:允许在列表中向前或向后移动,甚至可以进行特定定位,例如移至列表中的第四个记录或者从当前位置向后移动两个记录。不会受到其他用户对该数据库所作更改的影响。 
TYPE_SCROLL_SENSITIVE:象 TYPE_SCROLL_INSENSITIVE 一样,允许在记录中定位。这种类型受到其他用户所作更改的影响。如果用户在执行完查询之后删除一个记录,那个记录将从 ResultSet 中消失。类似的,对数据值的更改也将反映在 ResultSet 中。 
第二个参数设置 ResultSet 的并发性,该参数确定是否可以更新 ResultSet。其选项有: 
CONCUR_READ_ONLY:这是缺省值,指定不可以更新 
ResultSet CONCUR_UPDATABLE:指定可以更新 ResultSet 

  • 方法二 使用Statement加批量的方法

Java代码  收藏代码
  1.    
  2.  conn.setAutoCommit(false);  
  3.  Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);  
  4.  for(int x = 0; x < size; x++){  
  5.    stmt.addBatch("INSERT INTO adlogs(ip,website,yyyymmdd,hour,object_id) VALUES('192.168.1.3', 'localhost','20081009',8,'23123')");  
  6.  }  
  7. stmt.executeBatch();  
  8. conn.commit();  


  • 方法三:直接使用Statement
Java代码  收藏代码
  1. conn.setAutoCommit(false);  
  2. Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,  
  3.                                     ResultSet.CONCUR_READ_ONLY);  
  4. for(int x = 0; x < size; x++){  
  5.    stmt.execute("INSERT INTO adlogs(ip,website,yyyymmdd,hour,object_id) VALUES('192.168.1.3', 'localhost','20081009',8,'23123')");  
  6. }  
  7. conn.commit();  


使用上述方法分别插入10万条数据的平均测试时间为: 
方法一:17.844
方法二:18.421
方法三:16.359

可以看出JDBC的batch语句插入不但没有性能提升,反而比没有用batch的时候要慢,当然这可能跟JDBC具体驱动的实现方法有关。 附件中是我测试代码,可以用来在自己电脑上跑一下。 

在执行批量插入的时候最主要的是将自动提交取消,这样不管是否用JDBC的batch语法应该都没有关系。 
Java代码  收藏代码
  1. conn.setAutoCommit(false)  

本文转载地址:http://superjavason.iteye.com/blog/255423

0 0
原创粉丝点击