3

我需要从一个数据库中读取几百万行并将它们写入另一个。我想用PreparedStatement.addBatch大批量(可能是 1000 行)进行写入。我不需要他们参与交易。我正在用 Scala 2.9.2 编写代码。

一种方法如下:

val sourceResultSet = ...
val targetStatement = targetConnection.prepareStatement(...)
var rowCount = 0
while (sourceResultSet.next()) {
  // Read values from sourceResultSet and write them to targetStatement
  targetStatement.addBatch()
  rowCount += 1
  if (rowCount % 1000 == 0) {
    targetStatement.executeBatch()
    rowCount = 0
  }
}

我怎样才能以更实用的方式做到这一点,而不使用var rowCount? 我还需要考虑 RAM 的使用;我正在读取几百万行,因此任何涉及一次将所有源行都存储在内存中的解决方案都会失败。

4

1 回答 1

2

是什么类型的sourceResultSet?我假设根据您的使用情况使用 Iterator/Stream,但无论哪种方式,您都可以使用 Scala 集合take一次获取 1000 个元素(这适用于 Lists、Sets、Iterators、Streams 等)。为了在功能上做到这一点(虽然只是副作用,所以不是纯功能),定义一个内联函数:

def processSource(sourceResultSet: Iterator): Unit = {
  if(sourceResultSet.hasNext) {
    sourceResultSet.take(1000).foreach(row => /* Add to batch */)
    targetStatement.executeBatch()
    processResult(sourceResultSet) // How you handle the recursion depends on what sourceResultSet is
  }
}

val sourceResultSet = ...
val targetStatement = targetConnection.prepareStatement(...)
processSource(sourceResultSet)

只要 sourceResultSet 是惰性的(流或迭代器),这将避免一次将其加载到内存中。

于 2012-09-26T15:18:12.983 回答