Java讀取大文本文件保存到數據庫
1、追求效率
將文件讀取到內存,效率比較高,經過測試讀取1G左右的文本文件,機器內存消耗達到接近3個G,對內存消耗太大,不建議使用
2、通過調用第三方類庫實現
通過開源的Apache Commons IO流類庫提供的LineIterator對每行數據讀取,底層通過jdk中提供的BufferedReader實現,對內存的開銷不是很大
3、具體實現步驟
創建java項目引入pom依賴
1 <!-- https://mvnrepository.com/artifact/commons-io/commons-io --> 2 <dependency> 3 <groupId>commons-io</groupId> 4 <artifactId>commons-io</artifactId> 5 <version>2.4</version> 6 </dependency> 7 <!-- https://mvnrepository.com/artifact/ojdbc/ojdbc --> 8 <dependency> 9 <groupId>ojdbc</groupId> 10 <artifactId>ojdbc</artifactId> 11 <version>14</version> 12 </dependency>
具體實現代碼
1 package com.sun.file; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.sql.Connection; 6 import java.sql.DriverManager; 7 import java.sql.PreparedStatement; 8 import java.sql.SQLException; 9 import java.util.Date; 10 11 import org.apache.commons.io.FileUtils; 12 import org.apache.commons.io.LineIterator; 13 14 public class ReadCustomerFile { 15 16 int idx; 17 Connection conn = null; 18 PreparedStatement pstmt = null; 19 20 /** 21 * 使用commons-io.jar包的FileUtils的類進行讀取 22 * txt中內容文件的分割必須為|,java中需要加轉譯符號 23 * @Title: readTxtFileByFileUtils 24 * @author sunt 25 * @date 2017年11月13日 26 * @return void 27 */ 28 public void readTxtFileByFileUtils(String fileName) { 29 File file = new File(fileName); 30 31 dbConnection(); 32 33 try { 34 LineIterator lineIterator = FileUtils.lineIterator(file, "UTF-8"); 35 while (lineIterator.hasNext()) { 36 String line = lineIterator.nextLine(); 37 38 // 行數據轉換成數組 39 String[] custArray = line.split("\\|"); 40 insertCustInfo(custArray,"SQLLOADER"); 41 Thread.sleep(10); 42 } 43 } catch (IOException e) { 44 e.printStackTrace(); 45 } catch (InterruptedException e) { 46 e.printStackTrace(); 47 } finally { 48 dbDisConnection(); 49 } 50 } 51 52 /** 53 * 數據入庫的邏輯需要自己實現 54 * sqlBf.append("INSERT INTO TEMP_CUST_INFO(CUST_NO, CUST_NM, MOB_NO1) \n"); 55 sqlBf.append(" VALUES(? \n"); 56 sqlBf.append(" , ? \n"); 57 sqlBf.append(" , ?) \n"); 58 59 拼接sql最后結尾的括號不能丟失 60 * @Title: insertCustInfo 61 * @author sunt 62 * @date 2017年11月13日 63 * @return void 64 */ 65 public void insertCustInfo(String[] strArray,String tableName) { 66 try { 67 StringBuffer sqlBf = new StringBuffer(); 68 sqlBf.setLength(0); 69 70 sqlBf.append("INSERT INTO "+tableName+"(ID, NAME) \n"); 71 sqlBf.append(" VALUES(? \n"); 72 sqlBf.append(" , ?) \n"); 73 74 pstmt = conn.prepareStatement(sqlBf.toString()); 75 idx = 1; 76 pstmt.clearParameters(); 77 // pstmt.setInt(idx++, Integer.parseInt(strArray[0])); 78 pstmt.setString(idx++, strArray[0]); 79 pstmt.setString(idx++, strArray[1]); 80 81 pstmt.executeUpdate(); 82 } catch (SQLException e) { 83 e.printStackTrace(); 84 } finally { 85 if (pstmt != null) { 86 try { 87 pstmt.close(); 88 } catch (SQLException e) { 89 e.printStackTrace(); 90 } 91 } 92 } 93 } 94 95 /** 96 * 連接數據庫的基本信息 97 * @Title: dbConnection 98 * @author sunt 99 * @date 2017年11月13日 100 * @return Connection 101 */ 102 public Connection dbConnection() { 103 try { 104 Class.forName("oracle.jdbc.driver.OracleDriver"); 105 106 String url = "jdbc:oracle:thin:@192.168.40.30:1521:orcl"; 107 String user = "ACTIVITY1"; 108 String password = "ACTIVITY1"; 109 110 conn = DriverManager.getConnection(url, user, password); 111 System.out.println("Connection 開啟!"); 112 } catch (ClassNotFoundException e) { 113 e.printStackTrace(); 114 } catch (SQLException e) { 115 e.printStackTrace(); 116 } 117 118 return conn; 119 } 120 121 /** 122 * 關閉數據庫的連接 123 * @Title: dbDisConnection 124 * @author sunt 125 * @date 2017年11月13日 126 * @return void 127 */ 128 public void dbDisConnection() { 129 if (conn != null) { 130 try { 131 conn.close(); 132 System.out.println("Connection 關閉!"); 133 } catch (SQLException e) { 134 e.printStackTrace(); 135 } 136 } 137 } 138 139 //測試代碼 140 public static void main(String[] args) { 141 ReadCustomerFile rcf = new ReadCustomerFile(); 142 Long startTime = new Date().getTime(); 143 rcf.readTxtFileByFileUtils("F:\\lc_test.txt"); 144 System.out.println("導入數據總共耗時:" + (new Date().getTime() - startTime)/1000 + "秒"); 145 } 146 }
導入的文件模板(大約100百萬模擬數據),以|作為分隔符
導入數據庫成功
注意事項:
需要修改自己的數據庫連接信息和指定導入文本文件的路徑,insertCustInfo方法需要自己修改實現
