java mysql 文本导入数据语句_Java利用MYSQL LOAD DATA LOCAL INFILE实现大批量导入数据到MySQL...
Mysql load data的使用
數(shù)據(jù)庫中,最常見的寫入數(shù)據(jù)方式是通過SQL INSERT來寫入,另外就是通過備份文件恢復數(shù)據(jù)庫,這種備份文件在MySQL中是SQL腳本,實際上執(zhí)行的還是在批量INSERT語句。
在實際中,常常會遇到兩類問題:一類是數(shù)據(jù)導入,比如從word、excel表格或者txt文檔導入數(shù)據(jù)(這些數(shù)據(jù)一般來自于非技術(shù)人員通過OFFICE工具錄入的文檔);一類數(shù)據(jù)交換,比如從MySQL、Oracle、DB2數(shù)據(jù)庫之間的數(shù)據(jù)交換。
這其中就面臨一個問題:數(shù)據(jù)庫SQL腳本有差異,SQL交換比較麻煩。但是幾乎所有的數(shù)據(jù)庫都支持文本數(shù)據(jù)導入(LOAD)導出(EXPORT)功能。利用這一點,就可以解決上面所提到的數(shù)據(jù)交換和導入問題。
MySQL的LOAD DATAINFILE語句用于高速地從一個文本文件中讀取行,并裝入一個表中。文件名稱必須為一個文字字符串。下面以MySQL5為例說明,說明如何使用MySQL的LOADDATA命令實現(xiàn)文本數(shù)據(jù)的導入。
注意:這里所說的文本是有一定格式的文本,比如說,文本分行,每行中用相同的符號隔開文本等等。等等,獲取這樣的文本方法也非常的多,比如可以把word、excel表格保存成文本,或者是一個csv文件。
在項目中,使用的環(huán)境是快速上傳一個csv文件,原系統(tǒng)中是使用的db2數(shù)據(jù)庫,然后調(diào)用了與mysql的loaddata相似的一個函數(shù)sysproc.db2load。但是loaddata在mysql的存儲過程是不能使用的。采取的方法時在java代碼中調(diào)用此方法。
實現(xiàn)的例子:
準備測試表
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流導入到數(shù)據(jù)庫中。在實際的實現(xiàn)中也可以把文件上傳到服務(wù)器,然后讀文件再導入文件,此時load data的local參數(shù)應(yīng)該去掉,并且文件名應(yīng)該是完整的絕對路徑的名字。
最后附上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,...]]
總結(jié)
LOADDATA是一個很有用的命令,從文件中導入數(shù)據(jù)比insert語句要快,MySQL文檔上說要快20倍左右。但是命令的選項很多,然而大多都用不到,如果真的需要,用的時候看看官方文檔即可。
總結(jié)
以上是生活随笔為你收集整理的java mysql 文本导入数据语句_Java利用MYSQL LOAD DATA LOCAL INFILE实现大批量导入数据到MySQL...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql中外键的作用是什么_mysql
- 下一篇: eclipse导入github项目提示没