java mysql load data_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 LOAD DATA LOCAL INFILE实现大批量导入数据到MySQL

本文地址: http://www.cppcns.com/ruanjian/java/222452.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值