zoukankan      html  css  js  c++  java
  • 三种JDBC批量插入编程方法的比较

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

    • 方法一,使用PreparedStatement加批量的方法
    1. try {     
    2.       Class.forName("com.<a href="http://lib.csdn.net/base/mysql" class='replace_word' title="MySQL知识库" target='_blank' style='color:#df3434; font-weight:bold;'>mysql</a>.jdbc.Driver");     
    3.       conn = DriverManager.getConnection(o_url, userName, password);     
    4.       conn.setAutoCommit(false);     
    5.       String sql = "INSERT adlogs(ip,website,yyyymmdd,hour,object_id) VALUES(?,?,?,?,?)";     
    6.       PreparedStatement prest = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);     
    7.       for(int x = 0; x < size; x++){     
    8.          prest.setString(1, "192.168.1.1");     
    9.          prest.setString(2, "localhost");     
    10.          prest.setString(3, "20081009");     
    11.          prest.setInt(4, 8);     
    12.          prest.setString(5, "11111111");     
    13.          prest.addBatch();     
    14.       }     
    15.       prest.executeBatch();     
    16.       conn.commit();     
    17.       conn.close();     
    18. catch (SQLException ex) {     
    19.    Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null, ex);     
    20. catch (ClassNotFoundException ex) {     
    21.      Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null, ex);     
    22. }    

    说明下在建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加批量的方法
    1. conn.setAutoCommit(false);     
    2.  Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);     
    3.  for(int x = 0; x < size; x++){     
    4.    stmt.addBatch("INSERT INTO adlogs(ip,website,yyyymmdd,hour,object_id) VALUES('192.168.1.3', 'localhost','20081009',8,'23123')");     
    5.  }     
    6. stmt.executeBatch();     
    7. conn.commit();    
    • 方法三:直接使用Statement
    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.844s
    方法二:18.421s
    方法三:16.359s

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

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

    1. conn.setAutoCommit(false)    

    个人觉得第一种方法是最方便最实用的。

  • 相关阅读:
    npm, node, pm2 使用笔记
    没加证书的域名通过https访问,错误的访问到有证书的域名项目--已解决
    mysql数据库大表加索引
    上传大文件失败
    ifame 与父页面进行数据交互(跨域)
    windows平台编译PHP及扩展 和 踩过的坑
    vim 使用笔记
    git 在pull/push指定密钥文件
    记一次使用Xshell登陆提示所选用户密钥未在远程主机上注册
    学习网站与参考文档
  • 原文地址:https://www.cnblogs.com/shizhijie/p/7458757.html
Copyright © 2011-2022 走看看