Считывание данных с помощью QueryRunner выполняется относительно быстро даже для больших объемов данных.
Однако, когда я иду, чтобы вставить данные, это занимает гораздо больше времени. (50 записей занимает 10-20 секунд)
Я в основном пытаюсь прочитать записи из набора таблиц в одной базе данных в другую.
Я не могу использовать DB Links, потому что у меня нет прав на создание одной базы данных для другой.
Я не могу использовать команды Oracle COPY TO, потому что некоторые поля являются TIMESTAMPS, которые не поддерживаются командой COPY.
Я не могу использовать PL / SQL, потому что он должен быть динамическим.
Я рассматриваю возможность создания сценария оболочки или пакетного сценария с использованием SQL * Plus и SQL * Loader, но предпочел бы решение java.
Альтернативы QueryRunner тоже в порядке. Пока они могут вставлять данные относительно быстро.
Я предполагаю, что QueryRunner индивидуально запрашивает каждый набор значений в последовательности вместо одного запроса с набором входных значений.
Использование: Java 1.8, commons-dbcp: 1.4, commons-dbutils: 1.7
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbutils.BasicRowProcessor;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.RowProcessor;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
private final int colCount;
private final int commitCount;
private final String tableName;
private final String insertSql;
private final RowProcessor rowHandler = new BasicRowProcessor();
private final QueryRunner devQueryRunner;
@Override
public Long handle(ResultSet rs) throws SQLException {
long readCount = 0;
long writeCount = 0;
Object[][] params = new Object[commitCount][colCount];
try (Connection conn = devQueryRunner.getDataSource().getConnection()) {
int row = 0;
while (rs.next()) {
readCount++;
params[row++] = rowHandler.toArray(rs);
if (row >= commitCount) {
insertRunner.batch(conn, insertSql, params);
writeCount+=row;
row = 0;
}
}
if (row > 0) {
devQueryRunner.batch(conn, insertSql, Arrays.copyOf(params, row));
}
return readCount;
} finally {
if (logger.isInfoEnabled()) {
logger.info(tableName+"[readCount="+readCount+", writeCount="+writeCount+"]");
}
}
}
Обновление # 1
Время записи с использованием PreparedStatement (это слишком медленно):
Чтение 50: 0мс
Напишите 50: 1430мс
Чтение 50: 0 мс
Напишите 50: 1899мс
Чтение 50: 0 мс
Напишите 50: 805мс
Чтение 50: 0 мс
Напишите 50: 377мс
Чтение 50: 0 мс
Напишите 50: 1131мс
Чтение 50: 0 мс
Напишите 50: 859мс
Чтение 50: 0 мс
Напишите 50: 2131мс
Чтение 50: 0 мс
Напишите 50: 2355мс
Чтение 10000: 0 мс
Напишите 10000: 925584мс
Чтение 10000: 0 мс
Напишите 10000: 604083мс