JAVA从文本文件(txt)读取一百万条数据保存到数据库

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百万模拟数据),以|作为分隔符

JAVA从文本文件(txt)读取一百万条数据保存到数据库

导入数据库成功

JAVA从文本文件(txt)读取一百万条数据保存到数据库

注意事项:

  需要修改自己的数据库连接信息和指定导入文本文件的路径,insertCustInfo方法需要自己修改实现