Мне было интересно, есть ли способ привязать ArrayList (или любой другой список, если на то пошло) к PreparedStatement, который в конечном итоге будет использоваться для доступа к базе данных Oracle. Я нашел:
Альтернативы предложения PreparedStatement IN?
И это похоже на мою проблему, но этот вопрос более конкретен: я хотел бы привязать ArrayList к PreparedStatement для использования в Oracle, если это возможно, как это достигается?
Мэтт, все объекты, реализующие java.util.List, предоставляют операцию get (int), которая извлекает объект по указанному индексу. Он также предоставляет итератор. Оба они не являются обязательными: порядок может быть нечетным, но порядок существует. Итак, все реализации java.util.List являются упорядочены ...
... а в Java List обычно относится к контракту интерфейса java.util.List.




Что ж, судя по ответу на этот вопрос, особенно по комментариям к моему неправильному ответу в этом вопросе, вы не можете.
См. https://docs.oracle.com/javase/1.5.0/docs/guide/jdbc/getstart/mapping.html#996857.
Это полезная ссылка, но я не хотел этого. Извиняюсь.
Вы не можете привязать список к одному параметру в подготовленном операторе.
Сгенерируйте SQL с маркером параметра для каждого элемента в списке, например:
SELECT NAME FROM ITEM WHERE ID IN (?, ?, ?, ?)
Несмотря на то, что вы будете генерировать новый оператор для каждого запроса, я все же рекомендую использовать PreparedStatement. Если ваш список содержит экземпляры String, вы получите необходимое экранирование для защиты от SQL-инъекции.
Но даже если это безопасный тип, например объекты Integer, некоторые драйверы или промежуточное ПО могут кэшировать PreparedStatements и возвращать кэшированный экземпляр, если запрашивается та же форма. Конечно, потребуется некоторое тестирование. Если ваши списки сильно различаются по размеру, у вас будет много разных операторов, и плохо реализованный кеш может быть не подготовлен для обработки такого количества.
Это то, чего я боялся, но похоже, что вам действительно нужно сгенерировать «строку с вопросительным знаком» и добавить ее в свой общий оператор SQL. Ну что ж.
Вы не можете связать его напрямую. Есть способ передать массив в качестве параметра. Я понятия не имею, что вы хотите делать с ним на стороне базы данных, поэтому это может вам не помочь.
По сути, вам нужно создать в базе данных тип вложенной таблицы; построить объект 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')
В каком объеме? Как выглядит ваше утверждение (с заполнителями)? Я сомневаюсь, что есть общее решение этой проблемы, поскольку 1) длина List будет варьироваться и 2) количество заполнителей в вашем заявлении, скорее всего, не изменится. Кроме того, не все списки упорядочены.