Вставить в несколько таблиц с помощью jdbc

Я пытаюсь использовать JDBC для вставки в несколько таблиц. Поскольку это должно быть быстро, я хочу использовать PreparedStatement и метод executeBatch. Таблицы объединяются отношением внешнего ключа.

  • Первая идея состояла в том, чтобы использовать getGeneratedKeys(), но это не работает с некоторыми драйверами JDBC. Например. Постгрес SQL.

  • Вторая идея заключалась в использовании SQL-currval(...)-функции. Но необходимость вызывать пакет выполнения для одного оператора, а для другого делает все ключи одним и тем же значением. Так что этот метод тоже не работает.

  • JDBC не принимает вставки, разделенные точкой с запятой.

Как я могу этого добиться?


person hans.g    schedule 02.03.2011    source источник


Ответы (3)


Похоже, вы в основном используете PostgreSQL. Возможно, полезно знать, что начиная с версии драйвера PostgreSQL JDBC 8.4-701 PreparedStatement#getGeneratedKeys() полностью работоспособный.

Вам нужно только подготовить оператор следующим образом, чтобы он возвращал ключи:

statement = connection.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS);

Итак, при необходимости обновите драйвер и исправьте способ подготовки выписки. Кстати, это относится и ко многим другим драйверам JDBC.


Совершенно другая альтернатива — полностью отказаться от простого JDBC, перейти на один уровень абстракции и погрузиться в «старый добрый» Hibernate или современный JPA. Они предлагают чисто объектно-ориентированный подход к обработке объектов базы данных в Java без необходимости возиться с сгенерированными ключами и т.п. Все это прозрачно обрабатывается под обложками, и они поддерживают очень широкий спектр диалектов БД.

person BalusC    schedule 03.03.2011
comment
Спасибо за ответ. Вы хотите сказать, что функциональность в 8.4-701 была удалена в 9.0-801? Использование Statement.RETURN_GENERATED_KEYS вызывает исключение при вызове executeBatch(), говорящее, что он не ожидает результатов, но получает некоторые... Это работает в 8.4-701? - person hans.g; 03.03.2011

Если код должен работать быстро, попробуйте написать хранимую процедуру/функцию, которая будет принимать массивы значений, которые будут вставлены в таблицы.

Вот пример.

person Boris Pavlović    schedule 02.03.2011
comment
Благодарю. Моя проблема в том, что система очень динамична, например. могут быть добавлены новые таблицы и структуры. Необходимость затем определить дополнительную функцию на сервере postgres (она должна работать с любой базой данных JDBC, а не только с postgres) требует много работы. Есть ли способ генерировать процедуры через JDBC? Java-приложение должно быть центром системы - person hans.g; 02.03.2011

Хорошо, вот мой собственный ответ.

Пока поставщики не могут правильно реализовать функцию getGeneratedKeys(), которая вам нужна, и вариант резервного копирования для конкретной базы данных.

Делает код очень уродливым, если вам нужны запасные варианты для неспортивных баз данных.

Вот мой обходной путь для Postgres 9.0:

  • Сначала сгенерируйте большую загрузку ключей с помощью "SELECT nextval('public.\"table_column_seq\"') FROM generate_series(1,"+pollsize+")");
  • Затем раздайте эти ключи во всех подготовленных пакетных отчетах.

Потратил на это целый чертов день, а потом все, что я получаю, это уродливое решение. JDBC должен проверять при запуске приложения, действительно ли драйвер соответствует его ожиданиям, и в противном случае выдавать какое-то неисправимое злое YouVeGotaF**ckedUpDriverException.

person hans.g    schedule 02.03.2011