简体   繁体   English

MySQL,从已解析文件加载数据的最有效方法

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

My File has the following format: 我的文件具有以下格式:

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
...

Each batch of records starting from the next line after TableX header and ending by an empty line delimiter is about 700-800 lines size. 从TableX标头后的下一行开始,以空行定界符结束的每批记录的大小约为700-800行。

Each such batch of lines ( rec_xyz ...) need to be imported into the relevant MyISAM table name indicated in the header of the batch ( TableX ) 每行这样的批处理( rec_xyz ...)需要导入到批处理( TableX )标题中指示的相关MyISAM表名中。

I am familiar with the option to pipeline the stream using shell comands into LOAD DATA command. 我熟悉使用外壳命令将流传输到LOAD DATA命令的选项。

I am interested in simple java snipet code which will parse this file and execute LOAD DATA for a single batch of records each time (in a for loop and maybe using seek command). 我对简单的Java snipet代码感兴趣,该代码将解析此文件并每次都对单批记录执行LOAD DATA(在for循环中,也许使用seek命令)。

for now i am trying to use IGNORE LINES to jump over processed records, but i am not familiar if there is an option to ignore lines from BELOW? 现在,我正在尝试使用IGNORE LINES跳过已处理的记录,但是我不熟悉是否可以忽略BELOW下的行?

is there a more efficient way to parse and load this type of file into DB? 有没有更有效的方法来解析这种类型的文件并将其加载到数据库中?

EDIT 编辑

I have read that JDBC supports input stream to LOAD DATA starting from 5.1.3, can i use it to iterate over the file with an input stream and change the LOAD DATA statement each time? 我已经读过JDBC从5.1.3开始支持LOAD DATA输入流,我可以用它来遍历带有输入流的文件并每次更改LOAD DATA语句吗?

I am attaching my code as a solution, 我附上我的代码作为解决方案,

This solution is based on the additional functionality ( setLocalInfileInputStream ) added by MySQL Connector/J 5.1.3 and later. 该解决方案基于MySQL Connector / J 5.1.3及更高版本添加的附加功能setLocalInfileInputStream )。

I am pipe-lining input-stream into LOAD DATA INTO statement, instead of using direct file URL. 我将输入流通过管道传递到LOAD DATA INTO语句中,而不是使用直接文件URL。

Additional info: I am using BoneCP as a connection pool 附加信息:我正在使用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