我正在将大量数据从 CSV 文件导入 MSSQL Server 2008。我正在使用核心 JDBC(没有任何 ORM 框架)并使用 Microsoft 提供的驱动程序“sqljdbc4.jar”与数据库通信。
以下是我的要求:
- 按顺序解析 CSV 文件。
- 根据业务需求验证记录。(如果记录无效,则将错误记录在错误文件中的每条记录中。)
- 将未发现无效的记录导入数据库。(如果记录无效,则针对错误文件中的每条记录记录错误。)
- 保存两个结果文件成功和错误。成功将具有相同数量的具有良好记录的字段。错误文件将有一个带有错误的附加字段“错误”(从验证/导入面记录)。
截至目前,我正在一一导入记录。即使使用的是 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;
}
谢谢。