• Java不写文件,LOAD DATA LOCAL INFILE大批量导入数据到MySQL的实现(转)



    MySQL使用load data local infile 从文件中导入数据比insert语句要快,MySQL文档上说要快20倍左右。
    但是这个方法有个缺点,就是导入数据之前,必须要有文件,也就是说从文件中导入。这样就需要去写文件,
    以及文件删除等维护。某些情况下,比如数据源并发的话,还会出现写文件并发问题,很难处理。
    那么有没有什么办法,可以达到同样的效率,直接从内存(IO流中)中导入数据,而不需要写文件呢?
    前段时间,去MySQL社区的时候发现了这样一个方法:setLocalInfileInputStream(),此方法位于com.mysql.jdbc.PreparedStatement 类中

    通过使用 MySQL JDBC 的setLocalInfileInputStream 方法实现从Java InputStream中load data local infile 到MySQL数据库中。

     1 use test;  
     2 CREATE TABLE `test` (  
     3   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
     4   `a` int(11) NOT NULL,  
     5   `b` bigint(20) unsigned NOT NULL,  
     6   `c` bigint(20) unsigned NOT NULL,  
     7   `d` int(10) unsigned NOT NULL,  
     8   `e` int(10) unsigned NOT NULL,  
     9   `f` int(10) unsigned NOT NULL,  
    10   PRIMARY KEY (`id`),  
    11   KEY `a_b` (`a`,`b`)  
    12 ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 
     1     package com.seven.dbTools.DBTools;  
     2       
     3     import java.io.ByteArrayInputStream;  
     4     import java.io.InputStream;  
     5     import java.sql.Connection;  
     6     import java.sql.PreparedStatement;  
     7     import java.sql.SQLException;  
     8     import org.springframework.jdbc.core.JdbcTemplate;  
     9       
    10     import javax.sql.DataSource;  
    11       
    12     import org.apache.log4j.Logger;  
    13       
    14     /** 
    15      * @author seven 
    16      * @since 07.03.2013 
    17      */  
    18     public class BulkLoadData2MySQL {  
    19       
    20         private static final Logger logger = Logger.getLogger(BulkLoadData2MySQL.class);  
    21         private JdbcTemplate jdbcTemplate;  
    22         private Connection conn = null;  
    23       
    24         public void setDataSource(DataSource dataSource) {  
    25             this.jdbcTemplate = new JdbcTemplate(dataSource);  
    26         }  
    27       
    28         public static InputStream getTestDataInputStream() {  
    29             StringBuilder builder = new StringBuilder();  
    30             for (int i = 1; i <= 10; i++) {  
    31                 for (int j = 0; j <= 10000; j++) {  
    32       
    33                     builder.append(4);  
    34                     builder.append("	");  
    35                     builder.append(4 + 1);  
    36                     builder.append("	");  
    37                     builder.append(4 + 2);  
    38                     builder.append("	");  
    39                     builder.append(4 + 3);  
    40                     builder.append("	");  
    41                     builder.append(4 + 4);  
    42                     builder.append("	");  
    43                     builder.append(4 + 5);  
    44                     builder.append("
    ");  
    45                 }  
    46             }  
    47             byte[] bytes = builder.toString().getBytes();  
    48             InputStream is = new ByteArrayInputStream(bytes);  
    49             return is;  
    50         }  
    51       
    52         /** 
    53          *  
    54          * load bulk data from InputStream to MySQL 
    55          */  
    56         public int bulkLoadFromInputStream(String loadDataSql,  
    57                 InputStream dataStream) throws SQLException {  
    58             if(dataStream==null){  
    59                 logger.info("InputStream is null ,No data is imported");  
    60                 return 0;  
    61             }  
    62             conn = jdbcTemplate.getDataSource().getConnection();  
    63             PreparedStatement statement = conn.prepareStatement(loadDataSql);  
    64       
    65             int result = 0;  
    66       
    67             if (statement.isWrapperFor(com.mysql.jdbc.Statement.class)) {  
    68       
    69                 com.mysql.jdbc.PreparedStatement mysqlStatement = statement  
    70                         .unwrap(com.mysql.jdbc.PreparedStatement.class);  
    71       
    72                 mysqlStatement.setLocalInfileInputStream(dataStream);  
    73                 result = mysqlStatement.executeUpdate();  
    74             }  
    75             return result;  
    76         }  
    77       
    78         public static void main(String[] args) {  
    79             String testSql = "LOAD DATA LOCAL INFILE 'sql.csv' IGNORE INTO TABLE test.test (a,b,c,d,e,f)";  
    80             InputStream dataStream = getTestDataInputStream();  
    81             BulkLoadData2MySQL dao = new BulkLoadData2MySQL();  
    82             try {  
    83                 long beginTime=System.currentTimeMillis();  
    84                 int rows=dao.bulkLoadFromInputStream(testSql, dataStream);  
    85                 long endTime=System.currentTimeMillis();  
    86                 logger.info("importing "+rows+" rows data into mysql and cost "+(endTime-beginTime)+" ms!");  
    87             } catch (SQLException e) {  
    88                 e.printStackTrace();  
    89             }  
    90             System.exit(1);  
    91         }  
    92       
    93     }  

    提示:
    String testSql ="LOAD DATA LOCAL INFILE 'sql.csv' IGNORE INTO TABLE test.test (a,b,c,d,e,f)";

    使用setLocalInfileInputStream方法,会直接忽略掉文件名称,而直接将IO流导入到数据库中。
     

    参考:
    http://assets.en.oreilly.com/1/event/21/Connector_J%20Performance%20Gems%20Presentation.pdf

  • 相关阅读:
    jmeter-配置元件---计数器
    jmeter进行数据库测试
    jmeter取样器--FTP测试计划
    配置元件--HTTP授权管理器
    配置元件--HTTP Cookie Manager
    配置元件--HTTP Cache Manager
    配置元件-HTTP信息头管理器
    配置元件--csv data config
    jmeter-线程组
    jmeter-测试计划
  • 原文地址:https://www.cnblogs.com/dongruiha/p/6307289.html
Copyright © 2020-2023  润新知