jdbc连接Oracle/MySQL数据库进行批量导入操作,如何提高效率???
生活随笔
收集整理的這篇文章主要介紹了
jdbc连接Oracle/MySQL数据库进行批量导入操作,如何提高效率???
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
使用JDBC連接Oracle數據庫進行批量數據導入的時候,特別是大批量數據連續插入(百萬級或以上),如何提高效率呢?
在JDBC編程接口中有兩個方法特別值得注意:
(1)void addBatch() throws SQLException Adds a set of parameters to this?PreparedStatement?object's batch of commands.
(2)int[] executeBatch() throws SQLException Submits a batch of commands to the database for execution and if all commands execute successfully, returns an array of update counts. The?int?elements of the array that is returned are ordered to correspond to the commands in the batch, which are ordered according to the order in which they were added to the batch. 通過使用addBatch()和executeBatch()這一對方法可以實現批量處理數據。 不過值得注意的是,首先需要在數據庫鏈接中設置手動提交,connection.setAutoCommit(false),然后在執行Statement之后執行connection.commit()。 詳細步驟如下: (1)獲取數據庫連接 1》Oracle數據庫連接 package com.test.jdbc;import java.sql.Connection; import java.sql.DriverManager;import com.test.jdbc.IDBConnection; /*** 取得Oracle數據庫連接* */ public class OracleDBConnection implements IDBConnection {//DB Driverprivate static final String DBDRIVER="oracle.jdbc.driver.OracleDriver";//DB URLprivate static final String DBURL="jdbc:oracle:thin:@127.0.0.1:1521:orcl"; //DB Userprivate static final String DBUSER="xxtmanage";//DB Passwordprivate static final String DBPASSWORLD="xxtinterface";//DB Connectionprivate Connection conn=null;//structorpublic OracleDBConnection() {//在構造方法中進行數據庫連接System.out.println("OracleDBConnection.OracleDBConnection()");try {// 加載驅動程序Class.forName(DBDRIVER);//連接數據庫this.conn=DriverManager.getConnection(DBURL, DBUSER, DBPASSWORLD);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overridepublic Connection getConnection(){System.out.println("OracleDBConnection.getConnection()");return this.conn;}@Overridepublic void close(){System.out.println("OracleDBConnection.close()");if(this.conn!=null){try {this.conn.close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}} 2》MySQL數據庫連接 package com.xxxAM.dbc; import java.sql.Connection; import javax.naming.Context; import javax.naming.InitialContext; import javax.sql.DataSource; public class MySqlDBConnection {/*private static final String DBDRIVER="org.gjt.mm.mysql.Driver";private static final String DBURL="jdbc:mysql://localhost:3306/xxxamdb";private static final String DBUSER="root";private static final String DBPASS="123123";private Connection conn=null;public MySqlDBConnection () throws Exception{try{//加載驅動程序Class.forName(DBDRIVER);//連接數據庫this.conn=DriverManager.getConnection(DBURL,DBUSER,DBPASS);}catch(Exception e){throw e;}}public Connection getConnection()//取得數據庫連接{return this.conn;}//關閉數據庫操作public void close()throws Exception{if(this.conn!=null)//避免NullPointerException{try{this.conn.close();//數據庫關閉}catch(Exception e){throw e;}}}*///利用數據庫連接池,可以提高效率。。。private static final String DSNAME="java:comp/env/jdbc/xxxAM";private Connection conn=null;public DatabaseConnection()throws Exception{try{Context ctx=new InitialContext();DataSource ds=(DataSource)ctx.lookup(DSNAME);this.conn=ds.getConnection();}catch(Exception e){e.printStackTrace();}}public Connection getConnection(){return this.conn;}public void close()throws Exception{if(this.conn!=null){try{this.conn.close();}catch(Exception e){throw e;}}} } (2) 在數據庫中建表 建表操作不是本文的重點講解內容。為了簡單,這里直接給出編碼方式建表的sql語句,代碼如下: String sql="create table GPS_LOG_cxc"+ "( licenseplateno VARCHAR2(20) not null, "+ " in_date DATE default SYSDATE,"+ " gps_time DATE not null,"+ " longitude CHAR(10),"+ " latitude CHAR(9),"+ " height CHAR(9),"+ " speed CHAR(3),"+ " direction CHAR(3),"+ " eff CHAR(1),"+ " car_stat1 CHAR(1),"+ " car_stat2 CHAR(1)"+ ")";
當然,你也可以直接在數據中用sql語句或者手工建表 (3)兩種批量執行SQL語句的情況 為了簡單起見,直接在main()方法中編碼,代碼如下: 第一種情況:一個SQL語句的批量傳參: 1》PreparedStatement+batch (未使用clearBatch()方法時)處理方式 : package com.test.main;import java.sql.BatchUpdateException; import java.sql.Connection; import java.sql.PreparedStatement; import java.util.Date;import com.test.jdbc.OracleDBConnection;public class Test {public static void main(String[] args) throws Exception {// TODO Auto-generated method stub //得到Oracle數據庫連接Connection conn=new OracleDBConnection().getConnection();conn.setAutoCommit(false);//設置為不自動提交String sql="INSERT INTO GPS_LOG_cxc " + "(licenseplateno ,in_date,gps_time,longitude,latitude,height,speed, direction , eff, car_stat1, car_stat2)" +"VALUES(?,?,?,?,?,?,?,?,?,?,?)"; PreparedStatement pstmt=conn.prepareStatement(sql); //每n條命令commit一次 int n=10000; int[] updateCounts=null; //記錄起始時間 long startTime=System.currentTimeMillis(); //記錄命令執行失敗數 long faileNum=0; //記錄執行commit次數 long commitNum=0; for(int i=1;i<=1000000;i++){ pstmt.setString(1, "粵A434XX"); pstmt.setDate(2, new java.sql.Date(new Date().getTime())); pstmt.setDate(3, new java.sql.Date(new Date().getTime())); pstmt.setString(4, "+113.36671"); pstmt.setString(5, "+23.08077"); pstmt.setString(6, "000"); pstmt.setString(7, "100"); pstmt.setString(8, "000"); pstmt.setString(9, "1"); pstmt.setString(10,"1" ); pstmt.setString(11, "8"); pstmt.addBatch(); if(i%n==0){ try { pstmt.executeBatch(); conn.commit(); //pstmt.clearBatch();commitNum++; System.out.println("--commit-- "); } catch (BatchUpdateException bue) { // TODO Auto-generated catch block faileNum++; updateCounts=bue.getUpdateCounts(); } } } pstmt.executeBatch(); conn.commit(); //pstmt.clearBatch(); long endTime=System.currentTimeMillis();pstmt.close(); conn.close(); long time=(endTime-startTime)/1000; //統計數據 System.out.println("每次提交:"+n+"條"); System.out.println("提交次數:"+commitNum); System.out.println("失敗次數:"+faileNum); System.out.println("用時:"+time+"秒"); }}
程序中是以100萬條相同數據進行插入操作進行測試的,測試結果如下(跟機器性能有關系的哦): 一次為: 每次提交:10000條 提交次數:100 失敗次數:0 用時:18秒 再一次為: 每次提交:10000條 提交次數:100 失敗次數:0 用時:18秒 測試結果可能會有浮動的,,,建議多測幾次。 2》PreparedStatement+batch (使用clearBatch()方法時)處理方式 : package com.test.main;import java.sql.BatchUpdateException; import java.sql.Connection; import java.sql.PreparedStatement; import java.util.Date;import com.test.jdbc.OracleDBConnection;public class Test {public static void main(String[] args) throws Exception {// TODO Auto-generated method stub //得到Oracle數據庫連接Connection conn=new OracleDBConnection().getConnection();conn.setAutoCommit(false);//設置為不自動提交String sql="INSERT INTO GPS_LOG_cxc " + "(licenseplateno ,in_date,gps_time,longitude,latitude,height,speed, direction , eff, car_stat1, car_stat2)" +"VALUES(?,?,?,?,?,?,?,?,?,?,?)"; PreparedStatement pstmt=conn.prepareStatement(sql); //每n條命令commit一次 int n=10000; int[] updateCounts=null; //記錄起始時間 long startTime=System.currentTimeMillis(); //記錄命令執行失敗數 long faileNum=0; //記錄執行commit次數 long commitNum=0; for(int i=1;i<=1000000;i++){ pstmt.setString(1, "粵A434XX"); pstmt.setDate(2, new java.sql.Date(new Date().getTime())); pstmt.setDate(3, new java.sql.Date(new Date().getTime())); pstmt.setString(4, "+113.36671"); pstmt.setString(5, "+23.08077"); pstmt.setString(6, "000"); pstmt.setString(7, "100"); pstmt.setString(8, "000"); pstmt.setString(9, "1"); pstmt.setString(10,"1" ); pstmt.setString(11, "8"); pstmt.addBatch(); if(i%n==0){ try { pstmt.executeBatch(); conn.commit(); pstmt.clearBatch();commitNum++; System.out.println("--commit-- "); } catch (BatchUpdateException bue) { // TODO Auto-generated catch block faileNum++; updateCounts=bue.getUpdateCounts(); } } } pstmt.executeBatch(); conn.commit(); pstmt.clearBatch(); long endTime=System.currentTimeMillis();pstmt.close(); conn.close(); long time=(endTime-startTime)/1000; //統計數據 System.out.println("每次提交:"+n+"條"); System.out.println("提交次數:"+commitNum); System.out.println("失敗次數:"+faileNum); System.out.println("用時:"+time+"秒"); }} 測試結果如下: 每次提交:10000條 提交次數:100 失敗次數:0 用時:14秒
第二種是多條SQL語句的批量處理,即Statement+batch處理方式,代碼如下 package com.test.main; import java.sql.BatchUpdateException; import java.sql.Connection; import java.sql.Statement; import java.util.Date;import com.test.jdbc.OracleDBConnection;public class Test {public static void main(String[] args) throws Exception {// TODO Auto-generated method stub //得到Oracle數據庫連接Connection conn=new OracleDBConnection().getConnection();conn.setAutoCommit(false);//設置為不自動提交String sql="";Statement stmt=conn.createStatement();//每n條命令commit一次int n=100;//記錄起始時間 long startTime=new Date().getTime();//記錄命令執行失敗數long faileNum=0;//記錄執行commit次數long commitNum=0;for(int i=1;i<=1000;i++){sql="INSERT INTO GPS_LOG_cxc "+ "(licenseplateno ,in_date,gps_time,longitude,latitude,height,speed, direction , eff, car_stat1, car_stat2)"+"VALUES("+"'粵A434XX'"+","+"to_date('2014-9-1 15:02:23','yyyy-mm-dd hh24:mi:ss')"+","+"to_date('2014-9-1 15:02:23','yyyy-mm-dd hh24:mi:ss')"+","+"'+113.36671'"+","+"'+23.08077'"+","+"'0'"+","+"'1'"+","+"'2'"+","+"'3'"+","+"'0'"+","+"'1'"+")";stmt.addBatch(sql);if(i%n==0){try {stmt.executeBatch();conn.commit();stmt.clearBatch();commitNum++;System.out.println("--commit-- ");} catch (BatchUpdateException bue) {// TODO Auto-generated catch blockfaileNum++;System.out.println(bue.toString());}}}stmt.executeBatch();conn.commit();stmt.clearBatch();stmt.close();conn.close();long endTime=new Date().getTime();long time=(endTime-startTime)/1000;//統計數據System.out.println("每次提交:"+n+"條");System.out.println("提交次數:"+commitNum);System.out.println("失敗次數:"+faileNum);System.out.println("用時:"+time+"秒");} } 測試結果(1000條數據,每100條commit一次)如下: 每次提交:100條 提交次數:10 失敗次數:0 用時:331秒(ps:不知道為什么這樣會慢很多???---以后再找原因吧!!!)
最后注意:Oracle數據庫中關于java.sql.Date類型的寫法: 對于表中字段類型有java.sql.Date類型的表,在sql語句中要進行如下方形式的寫法(如上例程序中所示): to_date('2014-9-1 15:02:23','yyyy-mm-dd hh24:mi:ss')
總結
以上是生活随笔為你收集整理的jdbc连接Oracle/MySQL数据库进行批量导入操作,如何提高效率???的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 应用程序发布流程---碗
- 下一篇: 关于JDBC的一些笔记