Как связать ArrayList с PreparedStatement в Oracle?

Мне было интересно, есть ли способ привязать ArrayList (или любой вид списка) к этому разделу PreparedStatement, который в конечном итоге будет использоваться для доступа к базе данных Oracle. Я нашел:

Альтернативы предложения PreparedStatement IN?

И это похоже на мою проблему, но этот вопрос более конкретный: я хотел бы привязать ArrayList к PreparedStatement, который будет использоваться в Oracle, если это возможно, как это сделать?

Ответ 1

Вы не можете привязать список к одному параметру в подготовленном операторе.

Создайте SQL с маркером параметра для каждого элемента в списке, например:

SELECT NAME FROM ITEM WHERE ID IN (?, ?, ?, ?)

Даже если вы создадите новый оператор для каждого запроса, я по-прежнему рекомендую использовать PreparedStatement. Если ваш список содержит экземпляры String, вы получите необходимое экранирование для защиты от SQL-инъекции.

Но даже если это безопасный тип, например Integer, некоторые драйверы или промежуточное ПО могут кэшировать PreparedStatements и возвращать кешированный экземпляр, если запрашивается одна и та же форма. Конечно, некоторые испытания были бы необходимы. Если ваши списки сильно различаются по размеру, у вас будет много разных операторов, и плохо реализованный кеш может не быть подготовлен к работе с таким количеством.

Ответ 2

Вы не можете напрямую связать его. Существует способ передать массив в качестве параметра. Я понятия не имею, что вы хотите сделать с ним на стороне базы данных, чтобы это не помогло вам.

В принципе, вам нужно создать тип вложенной таблицы в базе данных; построить объект Java на основе этого типа, содержащий данные из вашего массива; и передать это как параметр.

Если вы создали эти объекты в базе данных:

CREATE OR REPLACE TYPE my_nested_table IS TABLE OF VARCHAR2(20);
CREATE TABLE my_table (a  my_nested_table) NESTED TABLE a STORE AS my_table_a;

Затем вы можете написать Java-код следующим образом:

String[] insertvalues = { "a", "b", "c" };
PreparedStatement p = conn.prepareStatement("INSERT INTO my_table VALUES( ? )");
ARRAY insertParameter = new ARRAY( a_desc, conn, insertvalues );
p.setArray( 1, insertParameter );
p.execute();

Результаты в Oracle выглядят следующим образом:

dev> select * from my_table;

A
--------------------------------------------------------------------------------
MY_NESTED_TABLE('a', 'b', 'c')