簡體   English   中英

MySQL,從已解析文件加載數據的最有效方法

[英]MySQL, Most efficient Way to Load Data from a parsed file

我的文件具有以下格式:

Table1; Info
rec_x11;rec_x21;rec_x31;rec_x41
rec_x12;rec_x22;rec_x32;rec_x42
...
\n
Table2; Info
rec_x11;rec_x21;rec_x31;rec_x41
rec_x12;rec_x22;rec_x32;rec_x42
...
\n
Table3; Info
rec_x11;rec_x21;rec_x31;rec_x41
rec_x12;rec_x22;rec_x32;rec_x42
...

從TableX標頭后的下一行開始,以空行定界符結束的每批記錄的大小約為700-800行。

每行這樣的批處理( rec_xyz ...)需要導入到批處理( TableX )標題中指示的相關MyISAM表名中。

我熟悉使用外殼命令將流傳輸到LOAD DATA命令的選項。

我對簡單的Java snipet代碼感興趣,該代碼將解析此文件並每次都對單批記錄執行LOAD DATA(在for循環中,也許使用seek命令)。

現在,我正在嘗試使用IGNORE LINES跳過已處理的記錄,但是我不熟悉是否可以忽略BELOW下的行?

有沒有更有效的方法來解析這種類型的文件並將其加載到數據庫中?

編輯

我已經讀過JDBC從5.1.3開始支持LOAD DATA輸入流,我可以用它來遍歷帶有輸入流的文件並每次更改LOAD DATA語句嗎?

我附上我的代碼作為解決方案,

該解決方案基於MySQL Connector / J 5.1.3及更高版本添加的附加功能setLocalInfileInputStream )。

我將輸入流通過管道傳遞到LOAD DATA INTO語句中,而不是使用直接文件URL。

附加信息:我正在使用BoneCP作為連接池

public final void readFile(final String path)
        throws IOException, SQLException, InterruptedException {
    File file = new File(path);

    final Connection connection = getSqlDataSource().getConnection();
    Statement statement = SqlDataSource.getInternalStatement(connection.createStatement());

    try{
        Scanner fileScanner = new Scanner(file);
        fileScanner.useDelimiter(Pattern.compile("^$", Pattern.MULTILINE));

        while(fileScanner.hasNext()){
            String line;
            while ((line = fileScanner.nextLine()).isEmpty());

            InputStream is = new ByteArrayInputStream(fileScanner.next().getBytes("UTF-8"));
            String [] tableName = line.split(getSeparator());
            setTable((tableName[0]+"_"+tableName[1]).replace('-', '_'));

            String sql = "LOAD DATA LOCAL INFILE '" + SingleCsvImportBean.getOsDependantFileName(file) + "' " 
                    + "INTO TABLE " + SqlUtils.escape(getTable()) 
                    + "FIELDS TERMINATED BY '" + getSeparator() 
                    + "' ESCAPED BY '' LINES TERMINATED BY '" + getLinefeed() + "' ";
            sql += "(" + implodeStringArray(getFields(), ", ") + ")";       
            sql += getSetClause();

            ((com.mysql.jdbc.Statement) statement).setLocalInfileInputStream(is);
            statement.execute(sql);         
        }
    }finally{
        statement.close();
        connection.close();
    }   
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM