Java利用MYSQL LOAD DATA LOCAL INFILE实现大批量导入数据到MySQL

Mysql load data的使用

数据库中,最常见的写入数据方式是通过SQL INSERT来写入,另外就是通过备份文件恢复数据库,这种备份文件在MySQL中是SQL脚本,实际上执行的还是在批量INSERT语句。

在实际中,常常会遇到两类问题:一类是数据导入,比如从word、excel表格或者txt文档导入数据(这些数据一般来自于非技术人员通过OFFICE工具录入的文档);一类数据交换,比如从MySQL、Oracle、DB2数据库之间的数据交换。

这其中就面临一个问题:数据库SQL脚本有差异,SQL交换比较麻烦。但是几乎所有的数据库都支持文本数据导入(LOAD)导出(EXPORT)功能。利用这一点,就可以解决上面所提到的数据交换和导入问题。

MySQL的LOAD DATAINFILE语句用于高速地从一个文本文件中读取行,并装入一个表中。文件名称必须为一个文字字符串。下面以MySQL5为例说明,说明如何使用MySQL的LOADDATA命令实现文本数据的导入。

注意:这里所说的文本是有一定格式的文本,比如说,文本分行,每行中用相同的符号隔开文本等等。等等,获取这样的文本方法也非常的多,比如可以把word、excel表格保存成文本,或者是一个csv文件。

在项目中,使用的环境是快速上传一个csv文件,原系统中是使用的db2数据库,然后调用了与mysql的loaddata相似的一个函数sysproc.db2load。但是loaddata在mysql的存储过程是不能使用的。采取的方法时在java代码中调用此方法。

实现的例子:

准备测试表

SQL如下:

USE test;

CREATE TABLE `test` (
	`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	`a` int(11) NOT NULL,
	`b` bigint(20) UNSIGNED NOT NULL,
	`c` bigint(20) UNSIGNED NOT NULL,
	`d` int(10) UNSIGNED NOT NULL,
	`e` int(10) UNSIGNED NOT NULL,
	`f` int(10) UNSIGNED NOT NULL,
	PRIMARY KEY (`id`),
	KEY `a_b` (`a`, `b`)
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARSET = utf8

Java代码如下:

package com.seven.dbTools.DBTools;

import org.apache.log4j.Logger;

import org.springframework.jdbc.core.JdbcTemplate;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import javax.sql.DataSource;

/**

 *
 @author seven
 *
 @since 07.03.2013
 */
public class BulkLoadData2MySQL {
  private static final Logger logger = Logger.getLogger(BulkLoadData2MySQL.class);
  private JdbcTemplate jdbcTemplate;
  private Connection conn = null;

  public void setDataSource(DataSource dataSource) {
    this.jdbcTemplate = new JdbcTemplate(dataSource);
  }

  public static InputStream getTestDataInputStream() {
    StringBuilder builder = new StringBuilder();

    for (int i = 1; i <= 10; i++) {
      for (int j = 0; j <= 10000; j++) {
        builder.append(4);

        builder.append("\t");

        builder.append(4 + 1);

        builder.append("\t");

        builder.append(4 + 2);

        builder.append("\t");

        builder.append(4 + 3);

        builder.append("\t");

        builder.append(4 + 4);

        builder.append("\t");

        builder.append(4 + 5);

        builder.append("\n");
      }
    }

    byte[] bytes = builder.toString().getBytes();

    InputStream is = new ByteArrayInputStream(bytes);

    return is;
  }

  /**

   *

   * load bulk data from InputStream to MySQL

   */
  public int bulkLoadFromInputStream(String loadDataSql,
    InputStream dataStream) throws SQLException {
    if (dataStream == null) {
      logger.info("InputStream is null ,No data is imported");

      return 0;
    }

    conn = jdbcTemplate.getDataSource().getConnection();

    PreparedStatement statement = conn.prepareStatement(loadDataSql);
    int result = 0;

    if (statement.isWrapperFor(com.mysql.jdbc.Statement.class)) {
      com.mysql.jdbc.PreparedStatement mysqlStatement = statement.unwrap(com.mysql.jdbc.PreparedStatement.class);

      mysqlStatement.setLocalInfileInputStream(dataStream);

      result = mysqlStatement.executeUpdate();
    }

    return result;
  }

  public static void main(String[] args) {
    String testSql = "LOAD DATA LOCAL INFILE 'sql.csv' IGNORE INTO TABLE test.test (a,b,c,d,e,f)";

    InputStream dataStream = getTestDataInputStream();

    BulkLoadData2MySQL dao = new BulkLoadData2MySQL();

    try {
      long beginTime = System.currentTimeMillis();

      int rows = dao.bulkLoadFromInputStream(testSql, dataStream);

      long endTime = System.currentTimeMillis();

      logger.info("importing " + rows +
        " rows data into mysql and cost " + (endTime - beginTime) +
        " ms!");
    } catch (SQLException e) {
      e.printStackTrace();
    }

    System.exit(1);
  }
}

提示:

例子中的代码使用setLocalInfileInputStream方法,会直接忽略掉文件名称,而直接将IO流导入到数据库中。在实际的实现中也可以把文件上传到服务器,然后读文件再导入文件,此时load data的local参数应该去掉,并且文件名应该是完整的绝对路径的名字。

最后附上LOAD DATA INFILE语法

LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name.txt'
  [REPLACE | IGNORE]
 INTO TABLE tbl_name
  [FIELDS
  [TERMINATED BY 'string']
  [[OPTIONALLY] ENCLOSED BY 'char']
  [ESCAPED BY 'char' ]
 ]
  [LINES
  [STARTING BY 'string']
 [TERMINATED BY 'string']
 ]
  [IGNORE number LINES]
 [(col_name_or_user_var,...)]
  [SET col_name = expr,...]]

总结

LOADDATA是一个很有用的命令,从文件中导入数据比insert语句要快,MySQL文档上说要快20倍左右。但是命令的选项很多,然而大多都用不到,如果真的需要,用的时候看看官方文档即可。

您可能感兴趣的文章:

  • Java实现批量向mysql写入数据的方法
  • java 下执行mysql 批量插入的几种方法及用时
  • java基于jdbc连接mysql数据库功能实例详解
  • java连接MySQL数据库的代码
  • java向mysql插入数据乱码问题的解决方法
  • java连接mysql数据库及测试是否连接成功的方法
  • Java中如何获取mysql连接的3种方法总结
(0)

相关推荐

  • java向mysql插入数据乱码问题的解决方法

    遇到java向mysql插入数据乱码问题,如何解决? MySQL默认编码是latin1 mysql> show variables like 'character%'; +--------------------------+--------------------------+ | Variable_name | Value | +--------------------------+--------------------------+ | character_set_client | la

  • java连接MySQL数据库的代码

    本文实例为大家分享了java连接MySQL数据库的具体代码,供大家参考,具体内容如下 package connect; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; public class Connect { //驱动程序位置 public static final String DBDRIVER="com.mysql.jdbc.Driver"; //连接地址

  • Java实现批量向mysql写入数据的方法

    本文实例讲述了Java实现批量向mysql写入数据的方法.分享给大家供大家参考,具体如下: private static String user = "root"; private static String pass = "123456"; private static String URL = "jdbc:mysql://192.168.1.116:3306/test"; public static void main(String args

  • java连接mysql数据库及测试是否连接成功的方法

    本文实例讲述了java连接mysql数据库及测试是否连接成功的方法.分享给大家供大家参考,具体如下: package com.test.tool; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement

  • java 下执行mysql 批量插入的几种方法及用时

    方法1: Java code 复制代码 代码如下: conn = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASS);        pstmt = conn                .prepareStatement("insert into loadtest (id, data) values (?, ?)");        for (int i = 1; i <= COUNT; i++) {    

  • Java中如何获取mysql连接的3种方法总结

    前言 本文主要来说说三种 Java 中获取 mysql 连接的方式,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: 第一种:传统的连接方式: 第二种:读取配置文件方式: 第三种:数据库连接池. 一.传统的连接方式: 首先在 src 目录下创建名为 lib 的文件夹,导入数据库驱动的 jar 包,随后 "add to build path". 1.注册驱动 Class.forName("com.mysql.jdbc.Driver"); 2.获取连接 S

  • java基于jdbc连接mysql数据库功能实例详解

    本文实例讲述了java基于jdbc连接mysql数据库的方法.分享给大家供大家参考,具体如下: 一.JDBC简介 Java 数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法.JDBC也是Sun Microsystems的商标.它JDBC是面向关系型数据库的. 1.JDBC架构: JDBC API支持两层和三层处理模型进行数据库访问,但在一般的JDBC体系结构由

  • Java利用MYSQL LOAD DATA LOCAL INFILE实现大批量导入数据到MySQL

    Mysql load data的使用 数据库中,最常见的写入数据方式是通过SQL INSERT来写入,另外就是通过备份文件恢复数据库,这种备份文件在MySQL中是SQL脚本,实际上执行的还是在批量INSERT语句. 在实际中,常常会遇到两类问题:一类是数据导入,比如从word.excel表格或者txt文档导入数据(这些数据一般来自于非技术人员通过OFFICE工具录入的文档):一类数据交换,比如从MySQL.Oracle.DB2数据库之间的数据交换. 这其中就面临一个问题:数据库SQL脚本有差异,

  • mysql load data infile 的用法(40w数据 用了3-5秒导进mysql)

    如果是导入有中文的数据,我的mysql 设置的utf8 字符集,所以你要导入的xxx.txt 文件也要保存utf-8的字符集,命令 load data infile "d:/Websites/Sxxxx/test1.txt" ignore into table `names` fields terminated by ',' enclosed by '"'; 不知道用replace 这个关键字的话,还是会乱码..不同.等高手回答. 在详细的介绍,推荐大家去看mysql手册去吧

  • mysql Load Data InFile 的用法

    首先创建一个表 Use Test; Create Table TableTest( `ID` mediumint(8) default '0', `Name` varchar(100) default '' ) TYPE=MyISAM; 向数据表导入数据 Load Data InFile 'C:/Data.txt' Into Table `TableTest` 常用如下: Load Data InFile 'C:/Data.txt' Into Table `TableTest` Lines Te

  • PHP上传Excel文件导入数据到MySQL数据库示例

    最近在做Excel文件导入数据到数据库.网站如果想支持批量插入数据,可以制作一个上传Excel文件,导入里面的数据内容到MySQL数据库的小程序. 要用到的工具: ThinkPHP:轻量级国产PHP开发框架.可在ThinkPHP官网下载. PHPExcel:Office Excel 文档的一个PHP类库,它基于微软的OpenXML标准和PHP语言.可在CodePlex官网下载.. 1.设计MySQL数据库product 创建product数据库 CREATE DATABASE product D

  • 利用PL/SQL从Oracle数据库导出和导入数据

    本文实例为大家分享了使用PL/SQL从Oracle数据库导出和导入数据的方法,供大家参考,具体内容如下 1.导出数据: 方式一:工具->导出用户对象->导出.sql文件 注:这种方式导出的是建表语句和存储过程语句 方式二:工具->导出表 注: 这里是导出表的结构和数据 第一种方式导出.dmp格式的文件,.dmp是二进制文件,可跨平台,还能包含权限,效率不错,用的最为广泛. 第二种方式导出.sql格式的文件,可用文本编辑器查看,通用性比较好,效率不如第一种,适合小数据量导入导出.尤其注意的

  • MySQL中使用load data命令实现数据导入的方法

    使用方式如下: 复制代码 代码如下: mysql>load data local infile "D:/ab.txt" into table mytbl(name,age); 使用上述的命令就可以将D:/ab.txt文件的内容导入到表mytbl中,其中name和age是表mytbl的字段,对应ab.txt文件中每行的数据.如果编译安装mysql时没有指定 –enable-local-infile,那么在使用上述命令时会报如下错误: 复制代码 代码如下: ERROR 1148 (4

  • MySQL 4种导入数据的方法

    1.mysql 命令导入 使用 mysql 命令导入语法格式为: mysql -u用户名 -p密码 < 要导入的数据库数据(runoob.sql) 实例: # mysql -uroot -p123456 < runoob.sql 以上命令将将备份的整个数据库 runoob.sql 导入. 2.source 命令导入 source 命令导入数据库需要先登录到数库终端: mysql> create database abc; # 创建数据库 mysql> use abc; # 使用已创

  • mysql 的load data infile

    LOAD DATA INFILE语句从一个文本文件中以很高的速度读入一个表中.如果指定LOCAL关键词,从客户主机读文件.如果LOCAL没指定,文件必须位于服务器上.(LOCAL在MySQL3.22.6或以后版本中可用.) 为了安全原因,当读取位于服务器上的文本文件时,文件必须处于数据库目录或可被所有人读取.另外,为了对服务器上文件使用LOAD DATA INFILE,在服务器主机上你必须有file的权限. 头一回用load data infile,以为只是把插入语句写到一个文件里,然后用loa

  • mysql中Load Data记录换行问题的解决方法

    问题是这样的: 表persons有两个字段: id和name文本文档persons.txt中内容(其中每行字段之间用tab分割):1    Bush2    Carter3    Bush 在mysql命令行下使用 load data local infile "persons.txt" into table persons 导入数据到persons表中. 导入后查看persons表的数据,与persons.txt的内容一致.但是使用语句select distinct name fro

  • mysql中的Load data的使用方法

    测试把txt文件导入至mysql数据库中: table: txt文件:D:/data.txt (txt文件下载) txt中使用 '\N' 描述null值. 导入数据: 复制代码 代码如下: load data local infile 'D:/data.txt' into table pet lines terminated by '\r\n' ignore 1 lines; 应用mysql版本:

随机推荐