PreparedStatement with list of parameters in a IN clause [duplicate]
PreparedStatement со списком параметров в предложении IN
Как установить значение для предложения in в PreparedStatement в JDBC при выполнении запроса.
Пример:
connection.prepareStatement("Select * from test where field in (?)");
Если это предложение in может содержать несколько значений, как я могу это сделать. Иногда я заранее знаю список параметров, а иногда и нет. Как справиться с этим случаем?
Переведено автоматически
Ответ 1
Что я делаю, так это добавляю "?" для каждого возможного значения.
varstmt= String.format("select * from test where field in (%s)", values.stream() .map(v -> "?") .collect(Collectors.joining(", ")));
Альтернативное использование StringBuilder (который был первоначальным ответом более 10 лет назад)
StringplaceHolders= builder.deleteCharAt( builder.length() -1 ).toString(); Stringstmt="select * from test where field in ("+ placeHolders + ")"; PreparedStatementpstmt= ...
А затем с радостью устанавливаем параметры
intindex=1; for( Object o : values ) { pstmt.setObject( index++, o ); // or whatever it applies }
Ответ 2
Вы могли бы использовать setArray метод, упомянутый в javadoc ниже:
PreparedStatementstatement= connection.prepareStatement("Select * from test where field in (?)"); Arrayarray= statement.getConnection().createArrayOf("VARCHAR", newObject[]{"A1", "B2","C3"}); statement.setArray(1, array); ResultSetrs= statement.executeQuery();
Ответ 3
Вы не можете заменить ? в своем запросе произвольное количество значений. Каждое ? является заполнителем только для одного значения. Для поддержки произвольного количества значений вам придется динамически создавать строку, содержащую ?, ?, ?, ... , ? с количеством вопросительных знаков таким же, как количество значений, которые вы хотите получить в своем in предложении.
Ответ 4
Вы не хотите использовать PreparedStatment с динамическими запросами, используя предложение IN, по крайней мере, вы уверены, что у вас всегда меньше переменной 5 или небольшого значения вроде этого, но даже так я думаю, что это плохая идея (не ужасная, но плохая). Поскольку количество элементов велико, будет хуже (и ужаснее ).
Представьте сотни или тысячи возможностей в вашем предложении IN :
Это контрпродуктивно, вы теряете производительность и память, потому что вы кэшируете каждый раз при новом запросе, а PreparedStatement предназначены не только для SQL-инъекции, речь идет о производительности. В этом случае лучше использовать Statement .
У вашего пула есть ограничение на PreparedStatment ( -1 по умолчанию, но вы должны его ограничить), и вы достигнете этого предела ! и если у вас нет лимита или очень большой лимит, у вас есть некоторый риск утечки памяти и, в крайнем случае, ошибок OutOfMemory. Итак, если это для вашего небольшого персонального проекта, которым пользуются 3 пользователя, это не драматично, но вы не хотите этого, если вы работаете в большой компании и вашим приложением пользуются тысячи людей и запрашивают миллионы.