真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java利用MYSQLLOADDATALOCALINFILE實(shí)現(xiàn)大批量導(dǎo)入數(shù)據(jù)到MySQL

MySQL load data的使用

創(chuàng)新互聯(lián)建站是一家專(zhuān)注網(wǎng)站建設(shè)、網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃、小程序設(shè)計(jì)、電子商務(wù)建設(shè)、網(wǎng)絡(luò)推廣、移動(dòng)互聯(lián)開(kāi)發(fā)、研究、服務(wù)為一體的技術(shù)型公司。公司成立十多年以來(lái),已經(jīng)為數(shù)千家濕噴機(jī)各業(yè)的企業(yè)公司提供互聯(lián)網(wǎng)服務(wù)?,F(xiàn)在,服務(wù)的數(shù)千家客戶(hù)與我們一路同行,見(jiàn)證我們的成長(zhǎng);未來(lái),我們一起分享成功的喜悅。

數(shù)據(jù)庫(kù)中,最常見(jiàn)的寫(xiě)入數(shù)據(jù)方式是通過(guò)SQL INSERT來(lái)寫(xiě)入,另外就是通過(guò)備份文件恢復(fù)數(shù)據(jù)庫(kù),這種備份文件在MySQL中是SQL腳本,實(shí)際上執(zhí)行的還是在批量INSERT語(yǔ)句。

在實(shí)際中,常常會(huì)遇到兩類(lèi)問(wèn)題:一類(lèi)是數(shù)據(jù)導(dǎo)入,比如從word、excel表格或者txt文檔導(dǎo)入數(shù)據(jù)(這些數(shù)據(jù)一般來(lái)自于非技術(shù)人員通過(guò)OFFICE工具錄入的文檔);一類(lèi)數(shù)據(jù)交換,比如從MySQL、Oracle、DB2數(shù)據(jù)庫(kù)之間的數(shù)據(jù)交換。

這其中就面臨一個(gè)問(wèn)題:數(shù)據(jù)庫(kù)SQL腳本有差異,SQL交換比較麻煩。但是幾乎所有的數(shù)據(jù)庫(kù)都支持文本數(shù)據(jù)導(dǎo)入(LOAD)導(dǎo)出(EXPORT)功能。利用這一點(diǎn),就可以解決上面所提到的數(shù)據(jù)交換和導(dǎo)入問(wèn)題。

MySQL的LOAD DATAINFILE語(yǔ)句用于高速地從一個(gè)文本文件中讀取行,并裝入一個(gè)表中。文件名稱(chēng)必須為一個(gè)文字字符串。下面以MySQL5為例說(shuō)明,說(shuō)明如何使用MySQL的LOADDATA命令實(shí)現(xiàn)文本數(shù)據(jù)的導(dǎo)入。

注意:這里所說(shuō)的文本是有一定格式的文本,比如說(shuō),文本分行,每行中用相同的符號(hào)隔開(kāi)文本等等。等等,獲取這樣的文本方法也非常的多,比如可以把word、excel表格保存成文本,或者是一個(gè)csv文件。

在項(xiàng)目中,使用的環(huán)境是快速上傳一個(gè)csv文件,原系統(tǒng)中是使用的db2數(shù)據(jù)庫(kù),然后調(diào)用了與mysql的loaddata相似的一個(gè)函數(shù)sysproc.db2load。但是loaddata在mysql的存儲(chǔ)過(guò)程是不能使用的。采取的方法時(shí)在java代碼中調(diào)用此方法。

實(shí)現(xiàn)的例子:

準(zhǔn)備測(cè)試表

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方法,會(huì)直接忽略掉文件名稱(chēng),而直接將IO流導(dǎo)入到數(shù)據(jù)庫(kù)中。在實(shí)際的實(shí)現(xiàn)中也可以把文件上傳到服務(wù)器,然后讀文件再導(dǎo)入文件,此時(shí)load data的local參數(shù)應(yīng)該去掉,并且文件名應(yīng)該是完整的絕對(duì)路徑的名字。

最后附上LOAD DATA INFILE語(yǔ)法

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是一個(gè)很有用的命令,從文件中導(dǎo)入數(shù)據(jù)比insert語(yǔ)句要快,MySQL文檔上說(shuō)要快20倍左右。但是命令的選項(xiàng)很多,然而大多都用不到,如果真的需要,用的時(shí)候看看官方文檔即可。


網(wǎng)站標(biāo)題:Java利用MYSQLLOADDATALOCALINFILE實(shí)現(xiàn)大批量導(dǎo)入數(shù)據(jù)到MySQL
文章鏈接:http://weahome.cn/article/ipoipi.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部