最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java實(shí)現(xiàn)jdbc批量插入數(shù)據(jù)

 更新時(shí)間:2016年05月08日 19:56:00   投稿:lijiao  
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)jdbc批量插入數(shù)據(jù),三種JDBC批量插入編程方法進(jìn)行比較,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

文章首先介紹三種JDBC批量插入編程方法,進(jìn)行比較,具體內(nèi)容如下

JDBC批量插入主要用于數(shù)據(jù)導(dǎo)入和日志記錄因?yàn)槿罩疽话愣际窍葘?xiě)在文件下的等。
我用Mysql 5.1.5的JDBC driver 分別對(duì)三種比較常用的方法做了測(cè)試

方法一:使用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); 
} 

說(shuō)明下在建Statement的時(shí)候,后面兩個(gè)參數(shù)的意義:
第一個(gè)參數(shù)指定 ResultSet 的類(lèi)型。其選項(xiàng)有:
TYPE_FORWARD_ONLY:缺省類(lèi)型。只允許向前訪(fǎng)問(wèn)一次,并且不會(huì)受到其他用戶(hù)對(duì)該數(shù)據(jù)庫(kù)所作更改的影響。
TYPE_SCROLL_INSENSITIVE:允許在列表中向前或向后移動(dòng),甚至可以進(jìn)行特定定位,例如移至列表中的第四個(gè)記錄或者從當(dāng)前位置向后移動(dòng)兩個(gè)記錄。不會(huì)受到其他用戶(hù)對(duì)該數(shù)據(jù)庫(kù)所作更改的影響。
TYPE_SCROLL_SENSITIVE:象 TYPE_SCROLL_INSENSITIVE 一樣,允許在記錄中定位。這種類(lèi)型受到其他用戶(hù)所作更改的影響。如果用戶(hù)在執(zhí)行完查詢(xún)之后刪除一個(gè)記錄,那個(gè)記錄將從 ResultSet 中消失。類(lèi)似的,對(duì)數(shù)據(jù)值的更改也將反映在 ResultSet 中。
第二個(gè)參數(shù)設(shè)置 ResultSet 的并發(fā)性,該參數(shù)確定是否可以更新 ResultSet。其選項(xiàng)有:
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萬(wàn)條數(shù)據(jù)的平均測(cè)試時(shí)間為:
方法一:17.844s
方法二:18.421s
方法三:16.359s

可以看出JDBC的batch語(yǔ)句插入不但沒(méi)有性能提升,反而比沒(méi)有用batch的時(shí)候要慢,當(dāng)然這可能跟JDBC具體驅(qū)動(dòng)的實(shí)現(xiàn)方法有關(guān)。 附件中是我測(cè)試代碼,可以用來(lái)在自己電腦上跑一下。

在執(zhí)行批量插入的時(shí)候最主要的是將自動(dòng)提交取消,這樣不管是否用JDBC的batch語(yǔ)法應(yīng)該都沒(méi)有關(guān)系。
conn.setAutoCommit(false) 

個(gè)人覺(jué)得第一種方法是最方便最實(shí)用的。

jdbc批量插入數(shù)據(jù) 例子講解:

最近做一個(gè)將excel數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫(kù)的程序時(shí),由于數(shù)據(jù)量大,準(zhǔn)備采用jdbc的批量插入。于是用了preparedStatement.addBatch();當(dāng)加入1w條數(shù)據(jù)時(shí),再執(zhí)行插入操作,preparedStatement.executeBatch()。我原以為這樣會(huì)很快,結(jié)果插入65536條數(shù)據(jù)一共花30多分鐘,完全出乎我的意料。于是問(wèn)了一下同事,他們?cè)谔幚磉@種大批量數(shù)據(jù)導(dǎo)入的時(shí)候是如何處理的,發(fā)現(xiàn)他們也是用的jdbc批量插入處理,但與我不同是:他們使用了con.setAutoCommit(false);然后再preparedStatement.executeBatch()之后,再執(zhí)行con.commit();于是再試,什么叫奇跡?就是剛剛導(dǎo)入這些數(shù)據(jù)花了半小時(shí),而加了這兩句話(huà)之后,現(xiàn)在只用了15秒鐘就完成了。于是去查查了原因,在網(wǎng)上發(fā)現(xiàn)了如下一段說(shuō)明:

    * When importing data into InnoDB, make sure that MySQL does not have autocommit mode enabled because that

      requires a log flush to disk for every insert. To disable autocommit during your import operation, surround it with

      SET autocommit and COMMIT statements:

      SET autocommit=0;
     ... SQL import statements ...
     COMMIT;

第一次,正是因?yàn)闆](méi)有setAutoCommit(false);那么對(duì)于每一條insert語(yǔ)句,都會(huì)產(chǎn)生一條log寫(xiě)入磁盤(pán),所以雖然設(shè)置了批量插入,但其效果就像單條插入一樣,導(dǎo)致插入速度十分緩慢。

部分代碼如下:

String sql = "insert into table *****";
con.setAutoCommit(false);
ps = con.prepareStatement(sql);
for(int i=1; i<65536; i++){
 ps.addBatch();
 // 1w條記錄插入一次
 if (i % 10000 == 0){
 ps.executeBatch();
 con.commit();
 }
}
// 最后插入不足1w條的數(shù)據(jù)
ps.executeBatch();
con.commit();

以上只是小菜,下面接著“上菜”:

1、測(cè)試批量寫(xiě)入數(shù)據(jù)

 long start = System.currentTimeMillis();
 DaoRecord daoRecord = new DaoRecord();
 List<T> list = new ArrayList<T>();
 for(int i = 1; i <= 1000; i++){
 for(int j = 1; j <= 1000; j++){
 T t = new T();
 t.setI(i);
 t.setJ(j);
 list.add(t);
 }
 }
 daoRecord.InsertBatch(list);
 System.out.println("耗時(shí):" + (System.currentTimeMillis()-start)+"毫秒");

2、批量寫(xiě)入數(shù)據(jù)測(cè)試

 public void InsertBatch(List<T> list){
 String sql = "insert into t(go,back) values(?,?)";
 DBHelper dbh = new DBHelper(sql);
 Connection conn = dbh.returnConn();
 try {
 conn.setAutoCommit(false);//注意此句一定要為false,原因見(jiàn)第一篇參考文獻(xiàn)
 PreparedStatement ps = conn.prepareStatement(sql);
 for(int i = 0; i < list.size(); i++){
 ps.setInt(1, list.get(i).getI());
 ps.setInt(2, list.get(i).getJ());
 ps.addBatch();
 if (i % 10000 == 0){
  ps.executeBatch();
  conn.commit();
  }
 }
 ps.executeBatch();
 conn.commit();
 conn.close();
 } catch (SQLException e) {
 // TODO 自動(dòng)生成的 catch 塊
 e.printStackTrace();
 }
 }

數(shù)據(jù)表:

實(shí)驗(yàn)結(jié)果:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • SpringBoot詳細(xì)講解靜態(tài)資源導(dǎo)入的實(shí)現(xiàn)

    SpringBoot詳細(xì)講解靜態(tài)資源導(dǎo)入的實(shí)現(xiàn)

    在Web開(kāi)發(fā)過(guò)程中,我們需要接觸許多靜態(tài)資源,如CSS、JS、圖片等;在之前的開(kāi)發(fā)中,這些資源都放在Web目錄下,用到的時(shí)候按照對(duì)應(yīng)路徑訪(fǎng)問(wèn)即可。不過(guò)在SpringBoot項(xiàng)目中,沒(méi)有了Web目錄,那這些靜態(tài)資源該放到哪里去,又要如何訪(fǎng)問(wèn)呢?這就是我們要講的靜態(tài)資源導(dǎo)入
    2022-05-05
  • jdk8的datetime時(shí)間函數(shù)使用示例

    jdk8的datetime時(shí)間函數(shù)使用示例

    這篇文章主要介紹了jdk8的datetime時(shí)間函數(shù)使用示例,需要的朋友可以參考下
    2014-03-03
  • java集合進(jìn)行排序的方式總結(jié)

    java集合進(jìn)行排序的方式總結(jié)

    在本篇文章里小編給大家整理的是一篇關(guān)于java集合進(jìn)行排序的兩種方式總結(jié),有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-08-08
  • java表單提交中文亂碼的解決方法

    java表單提交中文亂碼的解決方法

    這篇文章主要介紹了java表單提交中文亂碼的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • java實(shí)現(xiàn)批量下載 多文件打包成zip格式下載

    java實(shí)現(xiàn)批量下載 多文件打包成zip格式下載

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)批量下載、將多文件打包成zip格式下載,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Java中隨機(jī)函數(shù)變換的示例詳解

    Java中隨機(jī)函數(shù)變換的示例詳解

    這篇文章主要為大家詳細(xì)介紹了Java中隨機(jī)函數(shù)的變換,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,感興趣的可以了解一下
    2022-08-08
  • java實(shí)現(xiàn)將ftp和http的文件直接傳送到hdfs

    java實(shí)現(xiàn)將ftp和http的文件直接傳送到hdfs

    前面幾篇文章,我們已經(jīng)做了很好的鋪墊了,幾個(gè)要用到的工具我們都做了出來(lái),本文就是將他們集合起來(lái),說(shuō)下具體的用法,小伙伴們可以參考下。
    2015-03-03
  • 深入理解java內(nèi)置鎖(synchronized)和顯式鎖(ReentrantLock)

    深入理解java內(nèi)置鎖(synchronized)和顯式鎖(ReentrantLock)

    這篇文章主要介紹了Java多線(xiàn)程之內(nèi)置鎖(synchronized)和顯式鎖(ReentrantLock)的深入理解新的和用法,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • SpringBoot中@KafkaListener使用${}動(dòng)態(tài)指定topic問(wèn)題

    SpringBoot中@KafkaListener使用${}動(dòng)態(tài)指定topic問(wèn)題

    在SpringKafka中,使用${}引用Spring屬性配置,可以在不同環(huán)境中重新配置topic名稱(chēng),而無(wú)需修改代碼,在application.properties或application.yml中定義topic名稱(chēng),并在代碼中使用${}引用
    2024-12-12
  • JDK8中Optional類(lèi)巧用之判空操作

    JDK8中Optional類(lèi)巧用之判空操作

    善用Optional可以使我們代碼中很多繁瑣、丑陋的設(shè)計(jì)變得十分優(yōu)雅,這篇文章主要給大家介紹了JDK8中Optional類(lèi)巧用之判空的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-08-08

最新評(píng)論

安化县| 昭苏县| 祥云县| 富平县| 改则县| 云梦县| 五寨县| 彰化县| 上饶县| 漯河市| 阿瓦提县| 平塘县| 武乡县| 江源县| 石景山区| 丘北县| 米易县| 桂平市| 酒泉市| 江北区| 连江县| 永春县| 柏乡县| 曲靖市| 京山县| 盐津县| 浑源县| 米林县| 舒兰市| 新密市| 清流县| 玛沁县| 左权县| 石棉县| 呼伦贝尔市| 崇义县| 南京市| 基隆市| 微山县| 霍州市| 曲靖市|