Мне известен этот вопрос , но ответы не соответствуют тому, что я ищу (объяснено в конце).
Я хотел бы вставить несколько строк в порядка десятков или сотен тысяч, до MySQL версии базы данных 5.6 с Java.
Это будет выполняться неоднократно внутри тестов, поэтому я хотел бы сократить время, которое требуется.
В прошлом я делал подобные вещи с Node.js и Postgres и использовал два подхода:
.1 Использование jsonb_to_recordset
INSERT INTO some_table (a, b) SELECT x.a, x.b FROM json_to_recordset('[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]') AS x(a int, b text);
Массив будет передать в качестве параметра, и будет только один запрос вставки с таким количеством строк, как массив. Этот подход значительно быстрее, чем делать n вставок. И может управлять любым массивом, который легко помещается в памяти. Кроме того, запрос будет легко читать и сохранять c.
.2 Загрузка из потока узлов непосредственно в базу данных
pool.connect(function(err, client, done) {
var stream = client.query(copyFrom('COPY my_table FROM STDIN'));
var fileStream = fs.createReadStream('some_file.tsv')
fileStream.on('error', done);
stream.on('error', done);
stream.on('end', done);
fileStream.pipe(stream);
});
Этот параметр имеет очень низкий объем занимаемой памяти, и он может адаптироваться к потоку из файла или динамически генерируемого потока.
Возможно ли применить какой-либо из подходов в Java?
Вариант 1. Я предполагаю, что это невозможно в v 5.6, поскольку он не поддерживает JSON, но, возможно, в более новых версиях.
Вариант 2. mysql допускает загрузку файл с stdin вместо диска, поэтому потенциально hibernate может отправить поток java на mysql без загрузки всего в памяти.
В связанном вопросе есть и другие предложенные решения, но они не велики.
Принятый ответ:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
требует динамической записи запроса для корректировки на вход, также имеющего переменное число параметров и, возможно, группирования пакета по частям чтобы избежать слишком большого запроса.
Второе решение:
connection con.setAutoCommit(false);
PreparedStatement prepStmt = con.prepareStatement("UPDATE DEPT SET MGRNO=? WHERE DEPTNO=?");
prepStmt.setString(1,mgrnum1);
prepStmt.setString(2,deptnum1);
prepStmt.addBatch();
prepStmt.setString(1,mgrnum2);
prepStmt.setString(2,deptnum2);
prepStmt.addBatch();
int [] numUpdates=prepStmt.executeBatch();
Также потребует пакетирование в пакете, если слишком много записей, чтобы избежать проблемы с памятью.
Четвертое решение: вставка из файла. Имеет проблему, что требуется доступ к диску базы данных. .2 предложенное здесь было бы улучшенным решением.