`
superjavason
  • 浏览: 108742 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

三种JDBC批量插入编程方法的比较

    博客分类:
  • Java
阅读更多
JDBC批量插入主要用于数据导入和日志记录因为日志一般都是先写在文件下的等。
我用Mysql 5.1.5的JDBC driver 分别对三种比较常用的方法做了测试

  • 方法一,使用PreparedStatement加批量的方法
 
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加批量的方法

 
 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 INTO adlogs(ip,website,yyyymmdd,hour,object_id) VALUES('192.168.1.3', 'localhost','20081009',8,'23123')");
 }
stmt.executeBatch();
conn.commit();


  • 方法三:直接使用Statement
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 INTO adlogs(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语法应该都没有关系。
conn.setAutoCommit(false)


个人觉得第一种方法是最方便最实用的。
6
4
分享到:
评论
4 楼 jurs30 2013-09-03  
好东西,多谢楼主分享
3 楼 hzw2312 2012-08-10  
费解万分、我也测试了一下、用Hibernate的save方法、一条条的添加
hqlDao.save(customer);

既然比用batch快很多
conn.setAutoCommit(false);  //取消自动提交
			Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);  
			for(int x = 0; x < map.size(); x++){  
				CustomerManageInfo newinfo = (CustomerManageInfo)map.get(x);
				StringBuffer sqlInsert = new StringBuffer();  
				sqlInsert.append("INSERT INTO CUSTOMERMANAGE_BASICE_INFO ");
                                //此处set省略......
				sqlInsert.append(") "); 
				stmt.addBatch(sqlInsert.toString());
				stmt.executeBatch();
			}     
			try {
				conn.commit(); 
				bool = true;
			} catch (Exception e1) { 
				e1.printStackTrace();
				conn.rollback();
				bool = false;
			}     

Hibernate用了7秒、batch用了12秒、求解......
2 楼 qq1002517 2012-06-11  
我觉得也是。 batch不可能一点效率不提,不然人家开那方法干什么。
1 楼 xifanlou 2008-10-23  
弱弱的说一句:
那个...第一个是真正的批更新
后两个只是巧妙的执行了五次假更新,而且看样子是插入的重复数据,没有考虑主键么?
另外,再补充一句:
JDBC只是API,真正的批更新是怎么实现的要看数据库厂商,很多数据库没有更改协议,当执行Batch的时候,其实后台还是走的executeUpdate,是假的
真正的批更新是很牛X的,呵呵,直接插入上万组数据,与非批更新不可同日而语

相关推荐

    java实现jdbc批量插入数据

    主要为大家详细介绍了java实现jdbc批量插入数据,三种JDBC批量插入编程方法进行比较,感兴趣的朋友可以参考一下

    使用JDBC在MySQL数据库中如何快速批量插入数据

    在JDBC编程接口中Statement 有两个方法特别值得注意: void addBatch() throws SQLException Adds a set of parameters to this PreparedStatement object’s batch of commands. int[] executeBatch() throws ...

    java面试800题

    Q0060 JDBC批量更新的作用和用法 "提高执行效率。减少执行时间。 Statement sm = cn.createStatement(); sm.addBatch(sql1); sm.addBatch(sql2); ... sm.executeBatch() 或者 PreparedStatement ps = ...

    Java核心技术II(第8版)

    第四章 数据库编程 4.1 JDBC的设计 4.1.1 JDBC驱动程序类型 4.1.2 JDBC的典型用法 4.2 结构化查询语言 4.3 JDBC配置 4.3.1 数据库URL 4.3.2 驱动程序JAR文件 4.3.3 启动数据库 4.3.4 注册驱动器类 4.3.5 连接到...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例150 实例化Class类的5种方式 196 实例151 获得Class对象表示实体的名称 197 实例152 查看类的声明 198 实例153 查看类的成员 199 实例154 按继承层次对类排序 201 实例155 查看内部类信息 202 7.2 反射的进阶 ...

    Spring.3.x企业应用开发实战(完整版).part2

    11.3.3 插入Lob类型的数据 11.3.4 以块数据方式读取Lob数据 11.3.5 以流数据方式读取Lob数据 11.4 自增键和行集 11.4.1 自增键的使用 11.4.2 如何规划主键方案 11.4.3 以行集返回数据 11.5 其他类型的JDBCTemplate ...

    Spring3.x企业应用开发实战(完整版) part1

    11.3.3 插入Lob类型的数据 11.3.4 以块数据方式读取Lob数据 11.3.5 以流数据方式读取Lob数据 11.4 自增键和行集 11.4.1 自增键的使用 11.4.2 如何规划主键方案 11.4.3 以行集返回数据 11.5 其他类型的JDBCTemplate ...

    2017最新大数据架构师精英课程

    40_java事务管理-批量插入-存储过程 41_java mysql 函数 42_java mysql LongBlob + Text类型8 @9 ^) y7 s* L, _3 w7 Q9 q9 ^ 43_连接查询2 R: d" J9 J1 O3 D* B1 }2 u( {2 v 44_事务并发现象-脏读-幻读-不可重复读-...

    Spring中文帮助文档

    11.4. JDBC批量操作 11.4.1. 使用JdbcTemplate进行批量操作 11.4.2. 使用SimpleJdbcTemplate进行批量操作 11.5. 通过使用SimpleJdbc类简化JDBC操作 11.5.1. 使用SimpleJdbcInsert插入数据 11.5.2. 使用...

    Spring API

    11.4. JDBC批量操作 11.4.1. 使用JdbcTemplate进行批量操作 11.4.2. 使用SimpleJdbcTemplate进行批量操作 11.5. 通过使用SimpleJdbc类简化JDBC操作 11.5.1. 使用SimpleJdbcInsert插入数据 11.5.2. 使用...

    低清版 大型门户网站是这样炼成的.pdf

    5.6.1 批量插入 322 5.6.2 批量更新 323 5.6.3 批量删除 324 5.7 hibernate的事务管理 325 5.7.1 事务边界声明 325 5.7.2 并发控制 326 5.7.3 悲观锁 327 5.7.4 乐观锁 328 5.8 hibernate的缓存机制 332 ...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    13.1. 批量插入(Batch inserts) 13.2. 批量更新(Batch updates) 13.3. StatelessSession (无状态session)接口 13.4. DML(数据操作语言)风格的操作(DML-style operations) 14. HQL: Hibernate查询语言 14.1....

    Hibernate+中文文档

    13.1. 批量插入(Batch inserts) 13.2. 批量更新(Batch updates) 13.3. StatelessSession (无状态session)接口 13.4. DML(数据操作语言)风格的操作(DML-style operations) 14. HQL: Hibernate查询语言 14.1....

    HibernateAPI中文版.chm

    13.1. 批量插入(Batch inserts) 13.2. 批量更新(Batch updates) 13.3. StatelessSession (无状态session)接口 13.4. DML(数据操作语言)风格的操作(DML-style operations) 14. HQL: Hibernate查询语言 14.1....

    hibernate3.2中文文档(chm格式)

    13.1. 批量插入(Batch inserts) 13.2. 批量更新(Batch updates) 13.3. StatelessSession (无状态session)接口 13.4. DML(数据操作语言)风格的操作(DML-style operations) 14. HQL: Hibernate查询语言 14.1....

Global site tag (gtag.js) - Google Analytics