Java不寫檔案,LOAD DATA LOCAL INFILE大批量匯入資料到MySQL的實現
大家都知道當插入大批量資料MySQL的時候,
MySQL使用load data local infile 從檔案中匯入資料比insert語句要快,MySQL文件上說要快20倍左右。
但是這個方法有個缺點,就是匯入資料之前,必須要有檔案,也就是說從檔案中匯入。這樣就需要去寫檔案,
以及檔案刪除等維護。某些情況下,比如資料來源併發的話,還會出現寫檔案併發問題,很難處理。
那麼有沒有什麼辦法,可以達到同樣的效率,直接從記憶體(IO流中)中匯入資料,而不需要寫檔案呢?
前段時間,去MySQL社群的時候發現了這樣一個方法:setLocalInfileInputStream(),此方法位於com.mysql.jdbc.PreparedStatement 類中
下面是具體實現:
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資料庫中。
準備測試表
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 DEFAULT CHARSET=utf8
Java程式碼如下:
- package com.seven.dbTools.DBTools;
- import java.io.ByteArrayInputStream;
- import java.io.InputStream;
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.SQLException;
- import org.springframework.jdbc.core.JdbcTemplate;
- import javax.sql.DataSource;
- import org.apache.log4j.Logger;
- /**
- * @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);
- }
- }
提示:
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
http://jeffrick.com/2010/03/23/bulk-insert-into-a-mysql-database/
原創文章,歡迎轉載,轉載請註明出處:http://write.blog.csdn.net/postedit/9237495
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1839492/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 使用load data匯入資料到mysqlMySql
- 【轉貼】mysql匯入資料load data infile用法MySql
- MySQL 5.5使用LOAD DATA INFILE語句匯入資料MySql
- MySQL的文字匯入之load data localMySql
- 關於MySQL中使用LOAD DATA INFILE匯入csv檔案時的日期格式問題MySql
- Windows MySQL load data 命令中的infile 檔案目錄WindowsMySql
- MySQL INTO OUTFILE和LOAD DATA INFILE用法MySql
- MySQL資料匯入匯出之Load data fileMySql
- 【Mysql】匯出資料到excel檔案中MySqlExcel
- Java 匯入資料到Excel並提供檔案下載介面JavaExcel
- SQLServer匯出匯入資料到MySQLServerMySql
- 使用mysqlimport匯入資料到mysqlMySqlImport
- load data infile ERROR 1045 (28000)Error
- java程式碼實現excel檔案資料匯入JavaExcel
- MySQL load data載入資料MySql
- MYSQL資料檔案匯入MySql
- Python批量匯入Excel資料到MySQLPythonExcelMySql
- MySQL匯入匯出檔案檔案MySql
- GreatSQL 並行Load Data加快資料匯入SQL並行
- 故障分析 | MySQL 使用 load data 匯入資料錯誤的一個場景MySql
- Java實現CSV檔案的匯出Java
- 程式設計方式實現MySQL批量匯入sql檔案程式設計MySql
- spark sql與mysql 資料載入與匯出資料到mysqlSparkMySql
- mysql 匯入匯出 sql檔案MySql
- MySQL匯入匯出平面檔案MySql
- Mysql匯入csv檔案MySql
- Mysql匯入本地檔案MySql
- SQL通過bcp匯出資料到excel檔案SQLExcel
- java資料list寫入檔案Java
- 從CSV檔案匯入資料到Analytics Cloud裡建立模型和StoryCloud模型
- mysql匯入csv格式檔案MySql
- Java POI匯入Excel檔案JavaExcel
- oracle匯出資料到檔案中的方法 -- 轉自網路Oracle
- 向mysql中匯入.sql檔案MySql
- mysql匯入文字或excel檔案MySqlExcel
- 匯入網頁資料到 Google Sheet網頁Go
- 從EXCEL匯入資料到SQL SERVERExcelSQLServer
- 使用sqlldr匯入文字資料到oracleSQLOracle