0

我正在将大量数据从 CSV 文件导入 MSSQL Server 2008。我正在使用核心 JDBC(没有任何 ORM 框架)并使用 Microsoft 提供的驱动程序“sqljdbc4.jar”与数据库通信。

以下是我的要求:

  1. 按顺序解析 CSV 文件。
  2. 根据业务需求验证记录。(如果记录无效,则将错误记录在错误文件中的每条记录中。)
  3. 将未发现无效的记录导入数据库。(如果记录无效,则针对错误文件中的每条记录记录错误。)
  4. 保存两个结果文件成功和错误。成功将具有相同数量的具有良好记录的字段。错误文件将有一个带有错误的附加字段“错误”(从验证/导入面记录)。

截至目前,我正在一一导入记录。即使使用的是 PreparedStatement,这也需要相当多的时间。

我没有使用批量导入,因为我需要将确切的错误记录到错误文件中。

请提出任何在不牺牲准确错误记录的情况下提高性能的想法。我被迫在没有任何 ORM 工具的情况下这样做。

这是示例代码:

for (Map<String, String> csvRecord : csvAsList) {
    // Prepare category object using csvRecord.
    // invoke obj.insert(category);
}

public Category insert(Category category){

if (category == null) {
   return null;
}

String SQL = "INSERT INTO t1(c1,c2) VALUES(?,?)";
PreparedStatement pstmt = null;
ResultSet rs = null;

try {

   pstmt = this.dbConnectionUtil.getConnection().prepareStatement(SQL,
           Statement.RETURN_GENERATED_KEYS);

   pstmt.setInt(1, category.getField1());
   pstmt.setString(2, category.getField2());

   int result = pstmt.executeUpdate();

   if (result < 1) {
      return null;
   }

   rs = pstmt.getGeneratedKeys();
   if (rs.next()) {
      category.setId(rs.getInt(1));
   }

} finally {
   if (rs != null)
      rs.close();
   if (pstmt != null)
      pstmt.close();
   this.dbConnectionUtil.closeConnection();
}

return category;

}

2012 年 9 月 20 日更新。

我已经修改了代码,以便导入一个 CSV 文件,只会创建一个 PreparedStatement 对象。新代码如下:

public void importCSV(){
   // Create a db connection if its null or closed.
   // Create PreparedStatement objects for selects and inserts if null or closed.

   for (Map<String, String> csvRecord : csvAsList) {
      // Prepare category object using csvRecord.
      // Check whether category exists in by.
      // Import files can have up to 1,00,000 records so tracking errors is critical.
      try{
         categoryDAO.findByName(categoryName,<PreparedStatement object>);
      }
      catch(Exception exp){
         // log this to error.csv file
      }
      // If its a new category import it to the db.
      try{   
         categoryDAO.insert(category,<PreparedStatement object>);
      }
      catch(Exception exp){
         // log this to error.csv file
      }
   }

   // Close PreparedStatement objects
   // Close DB Connection

}

public Category insert(Category category,PreparedStatement pstmt ) throws SQLException{

if (category == null) {
   return null;
}

ResultSet rs = null;
try {

   pstmt.setInt(1, category.getField1());
   pstmt.setString(2, category.getField2());

   int result = pstmt.executeUpdate();

   if (result < 1) {
      return null;
   }

   rs = pstmt.getGeneratedKeys();
   if (rs.next()) {
      category.setId(rs.getInt(1));
   }

} finally {
   if (rs != null)
      rs.close();
}
return category;

}

谢谢。

4

1 回答 1

3

看起来您正在prepareStatement为输入数据的每一行再次调用。这几乎可以消除使用PreparedStatement. 相反,PreparedStatement在循环外部创建,在循环内部只保留setInt,setStringexecuteUpdate调用。

于 2012-09-18T20:43:48.040 回答