JDBC не позволяет создавать пакетные SELECT
запросы, что, на мой взгляд, является досадным ограничением, особенно потому, что подготовленные операторы не позволяют указывать переменное количество аргументов, например, предложение IN (...)
.
Ссылка на статью JavaRanch, на которую ссылается FJ, предлагает имитировать пакетирование путем создания серии запросов фиксированного размера и объединения их результатов, что кажется мне громоздким и неоптимальным исправлением;Вы должны вручную создавать и обрабатывать несколько запросов, а также обращаться к базе данных несколько раз.Если числа, выбранные для заданных вручную пакетов, невелики, вы можете в конечном итоге попасть в базу данных несколько раз, просто чтобы ответить на простой запрос.
Вместо этого я принял решение динамически создавать PreparedStatement
объекты сколичество полей мне нужно.Это означает, что потенциально мы создаем большее число PreparedStatement
с, чем при ручном пакетировании, но мы ограничиваем частоту попадания в базу данных и упрощаем нашу реализацию, обе из которых я считаю более важными.
/**
* Use this method to create batch-able queries, e.g:
* "SELECT * FROM t WHERE x IN (?, ?, ?, ?)"
* Can be built as:
* "SELECT * FROM t where x IN ("+getLineOfQs(4)+")"
*/
public static String getLineOfQs(int num) {
// Joiner and Iterables from the Guava library
return Joiner.on(", ").join(Iterables.limit(Iterables.cycle("?"), num));
}
/**
* Gets the set of IDs associated with a given list of words
*/
public Set<Integer> find(Connection conn, List<String> words)
throws SQLException {
Set<Integer> result = new HashSet<>();
try(PreparedStatement ps = conn.prepareStatement(
"SELECT id FROM my_table WHERE word IN ("+
getLineOfQs(words.size())+")")) {
for(int i = 0; i < words.size(); i++) {
ps.setString(i+1, words.get(i));
}
try (ResultSet rs = ps.executeQuery()) {
while(rs.next()) {
result.add(rs.getInt("id"));
}
}
}
return result;
}
Это не слишком болезненно для кода, обеспечивает безопасность использования PreparedStatement
и позволяет избежать ненужных обращений к базе данных.