jdbc-批量插入、批量删除、批量更新

一、JDBC的批量插入

JDBC批量插入主要用于数据导入和日志记录因为日志一般都是先写在文件下的等。
    我用Mysql5.1.5的JDBC driver 分别对三种比较常用的方法做了测试
   方法一,使用PreparedStatement加批量的方法
   Java代码     
  try{

     Class.forName("com.MySQL.jdbc.Driver");
     conn = DriverManager.getConnection(o_url, userName,password);
     conn.setAutoCommit(false);
     String sql = "INSERT adlogs(ip,website,yyyymmdd,hour,object_id)VALUES(?,?,?,?,?)";
     PreparedStatement prest =conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
     for(int x = 0; x < size;x++){
        prest.setString(1,"192.168.1.1");
        prest.setString(2,"localhost");
        prest.setString(3,"20081009");
        prest.setInt(4,8);
        prest.setString(5,"11111111");
        prest.addBatch();
     }
     prest.executeBatch();
     conn.commit();
     conn.close();
} catch (SQLException ex){
  Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null,ex);
} catch (ClassNotFoundException ex){
    Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null,ex);
}   

说明下在建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代码

 conn.setAutoCommit(false);
 Statement stmt =conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
 for(int x = 0; x < size;x++){
   stmt.addBatch("INSERT INTOadlogs(ip,website,yyyymmdd,hour,object_id) VALUES(‘192.168.1.3‘,‘localhost‘,‘20081009‘,8,‘23123‘)");
 }
stmt.executeBatch();
conn.commit();   

方法三:直接使用Statement
Java代码

conn.setAutoCommit(false);
Statement stmt =conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                                   ResultSet.CONCUR_READ_ONLY);
for(int x = 0; x < size;x++){
   stmt.execute("INSERT INTOadlogs(ip,website,yyyymmdd,hour,object_id) VALUES(‘192.168.1.3‘,‘localhost‘,‘20081009‘,8,‘23123‘)");
}
conn.commit();  

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

方法一:17.844s
方法二:18.421s
方法三:16.359s

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

在执行批量插入的时候最主要的是将自动提交取消,这样不管是否用JDBC的batch语法应该都没有关系。

Java代码

conn.setAutoCommit(false)  

二、JDBC的批量更新

于阿堂在原来的老项目中,用jdbc操作时,用到了jdbc的批量操作,加上前段时间看《疯狂java讲义》时,也看到李刚作者的相关介绍。考虑还是会有人要用到jdbc的操作的,所以,阿堂还是把它整一下,就成了下面的文字了。用JDBC的DML语句时(insert,delete,update),我们可能可能需要同时某几个表都要进行DML操作,比如,当我们对A表插入的时候,同时也要对B表插入相关的记录,还要同时更新C表的关联记录,这样就会涉及到三条DML的sql语句,如果不用批量更新功能的话,我们就得单独去处理,效率相对就要低些了。。使用批量更新时,多条sql语句将会被作为一批操作被同时收集,并同时提交。值得注意的是,批量更新必须得到底层数据库的支持,可能通过DatabaseMetaData的supportBatchUpdates方法来查看底层数据库是否支持批量更新

//conn是Connection的类型
  DatabaseMetaDatadbmd=conn.getMetaData();
//若a为true则意味着该数据是支持批量更新的
boolean a=dbmd.supportsBatchUpdates();

为了保证批量更新的操作可以正确处理错务,必须把批量更新的操作视为单个事务,如果批理更新在执行过程中失败,则让事务回滚到操作开始之前的状态。为了达到这种效果,程序应该在开始批量操作之前先关闭自动提交,然后开始收集更新语句,当批量操作执行结束后,提交事务,并恢复之前的自动提交模式
 具体如下代码片断所示

 try
 {
  //保存当前自动提交模式
  booleanautoCommit=conn.getAutoCommit();
  //关闭自动提交
  conn.setAutoCommit(false);
  //使用Statement同时收集多条sql语句
  stmt.addBatch(insert_sql1);
  stmt.addBatch(insert_sql2);
  stmt.addBatch(update_sql3);
  ..
  //同时提交所有的sql语句
  stmt.executeBatch();
  //提交修改
  conn.commit();
  conn.setAutoCommit(autoCommit);
 }
 catch(Exception e)
 {
    e.printStackTrace()
    conn.rollback();
 }

附:需要说明的一点是,如果是addBatch()方法中加了select查询语句,程序将直接出现错务的

这个又是一种方法批量进行更新。但是我认为上面那个方法不错

tx=session.beginTransaction();
Connection con = session.connection();
PreparedStatement stmt = con.prepareStatement(
     "update CUSTOMERS set AGE=AGE+1 where AGE>0");
stmt.excuteUpdate();
tx.commit();

三、JDBC批量删除

String sql="delete from table where idin(0";
String id[]=要删除的ID数组;
for(int i=0;i<id.length;i++)
{
  sql+=","+id[i];
}
sql+=")";
PreparedStatementps=conn.prepareStatement(sql);
ps.execute(); 

 public void deleteBat(Integer[] catNo){
try {
    Connection con=DBUtil.getInstance().getCon();
    String sql="delete from cat where catno=?";
    con.setAutoCommit(false);
    PreparedStatement ps=con.prepareStatement(sql);
    for (Integer in : catNo) {
        ps.setInt(1, in);
        ps.addBatch();
    }
    int[] result=ps.executeBatch();
    con.commit();
    for (int i : result) {
        System.out.println(i);
    }
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (SQLException e) {
    e.printStackTrace();
}
时间: 2024-11-05 13:26:10

jdbc-批量插入、批量删除、批量更新的相关文章

JDBC连接数据库(MySql)步骤,以及查询、插入、删除、更新等十一个处理数据库信息的功能。

主要内容:  JDBC连接数据库步骤. 一个简单详细的查询数据的例子. 封装连接数据库,释放数据库连接方法. 实现查询,插入,删除,更新等十一个处理数据库信息的功能. 把十一个功能都放在一起. 一.JDBC连接数据库(编辑)步骤(主要有六个步骤).  1.注册驱动: Class.formName("com.mysql.jdbc.Driver");  2.获取连接:(1) param1:  要连接数据库的url-----> String url="jdbc:mysql:/

JDBC连接(MySql)数据库步骤,以及查询、插入、删除、更新等十一个处理数据库信息的功能

主要内容:  JDBC连接数据库步骤. 一个简单详细的查询数据的例子. 封装连接数据库,释放数据库连接方法. 实现查询,插入,删除,更新等十一个处理数据库信息的功能.(包括事务处理,批量更新等) 把十一个功能都放在一起. 安装下载的数据库驱动程序jar包,不同的数据库需要不同的驱动程序(这本该是第一步,但是由于属于安装类,所以我们放在最后) 一.JDBC连接数据库(编辑)步骤(主要有六个步骤).  1.注册驱动: Class.forName("com.mysql.jdbc.Driver"

SqlBulkCopy与触发器,批量插入表(存在则更新,不存在则插入)

临时表:Test /****** 对象: Table [dbo].[Test] 脚本日期: 05/10/2013 11:42:07 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Test]( [ID] [int] IDENTITY(1,1) NOT NULL, [UserID] [int] NOT NULL, [UserName] [nvarchar](50) COLLATE Chines

mybatis使用foreach进行批量插入和删除操作

一.批量插入 1.mapper层 int insertBatchRoleUser(@Param("lists") List<RoleUser> lists);//@Param中的参数必须和mapper.xml中foreach的collection对应,若果不写@Param注解并且只传入一个list作为参数,则collection默认填list 2.mapper.xml <insert id="insertBatchRoleUser"> INS

Document插入、删除、更新

1.插入文档 db.[documentName].insert({...}) 2.批量插入文档 shell这样执行是错误的 db.[documentName].insert([{},{},{},...]) shell不支持批量插入 想完成批量插入可以用mongo的应用驱动或者是shell的for循环 3.Save操作 save操作和insert操作区别在于当遇到_id相同的情况下 save完成保存操作(覆盖_id相同的数据) insert则会报错 4.删除列表中所有数据 db.[document

Mysql数据库理论基础之七--插入、删除、更新语句

一.简介 由MySQL AB公司开发,是最流行的开放源码SQL数据库管理系统,主要特点: 1.是一种数据库管理系统 2.是一种关联数据库管理系统 3.是一种开放源码软件,且有大量可用的共享MySQL软件 4.MySQL数据库服务器具有快速.可靠和易于使用的特点 5.MySQL服务器工作在客户端/服务器模式下,或嵌入式系统中 InnoDB存储引擎将InnoDB表保存在一个表空间内,该表空间可由数个文件创建.这样,表的大小就能超过单独文件的最大容量.表空间可包括原始磁盘分区,从而使得很大的表成为可能

MySql学习之插入、删除和更新

一.插入数据 INSERT是用来插入(或添加)行到数据库表的.插入可 以用几种方式使用: ? 插入完整的行: ? 插入行的一部分: ? 插入多行: ? 插入某些查询的结果. 1.简单但是不安去 INSERT INTO customers VALUES( NULL, 'person'); 此例子插入一个新客户到customers表.存储到每个表列中的数据在VALUES子句中给出,对每个列必须提供一个值.如果某个列没有值(如上面的cust_contact和cust_email列),应该使用NULL值

二叉排序树(插入、删除、更新、遍历、搜索、求树高。。。)

#include <iostream> using namespace std; // 有序二叉树(二叉搜索树) class Tree { public: // 构造过程中初始化为空树 Tree (void) : m_root (NULL), m_size (0) {} // 析构过程中销毁剩余节点 ~Tree (void) { clear (); } // 插入数据 void insert (int data) { insert (new Node (data), m_root); ++m_

sql server中批量插入与更新两种解决方案分享

若只是需要大批量插入数据使用bcp是最好的,若同时需要插入.删除.更新建议使用SqlDataAdapter我测试过有很高的效率,一般情况下这两种就满足需求了 bcp方式 复制代码 代码如下: /// <summary> /// 大批量插入数据(2000每批次) /// 已采用整体事物控制 /// </summary> /// <param name="connString">数据库链接字符串</param> /// <param n

批量插入数据(基于Mybatis的实现-Oracle)

前言:做一个数据同步项目,要求:同步数据不丢失的情况下,提高插入性能. 项目DB框架:Mybatis.DataBase:Oracle. ---------------------------------------------------------------------------- 批量插入数据方式: 一.Mybatis 全局设置批处理: 二.Mybatis 局部设置批处理: 三.Mybatis foreach批量插入: ①SELECT UNION ALL: ②BEGIN INSERT I