Java PreparedStatement.addBatch()能否用于SELECT查询?
假设我有100个SELECT查询,每个查询的输入不同。值可以使用PreparedStatement 我在网上看到的所有文档都是批量插入/更新/删除的。我从未见过用于select语句的批处理 这能做到吗?如果是这样,请帮我当下面的示例代码 我想这可以使用IN子句来完成,但我更喜欢使用批处理select语句 示例代码: public void run(Connection db_conn, List value_list) { String sql = "SELECT * FROM DATA_TABLE WHERE ATTR = ?"; PreparedStatement pstmt = db_conn.prepareStatement(sql); for (String value: value_list) { pstmt.clearParameters(); pstmt.setObject(1, value); pstmt.addBatch(); } // What do I call here? int[] result_array = pstmt.executeBatch() while (pstmt.getMoreResults()) { ResultSet result_set = pstmt.getResultSet(); // do work here } }Java PreparedStatement.addBatch()能否用于SELECT查询?,java,sql,prepared-statement,Java,Sql,Prepared Statement,假设我有100个SELECT查询,每个查询的输入不同。值可以使用PreparedStatement 我在网上看到的所有文档都是批量插入/更新/删除的。我从未见过用于select语句的批处理 这能做到吗?如果是这样,请帮我当下面的示例代码 我想这可以使用IN子句来完成,但我更喜欢使用批处理select语句 示例代码: public void run(Connection db_conn, List value_list) { String sql = "SELECT * FROM DATA
我想这也可能是司机的行为。我正在使用IBM AS/400 DB2数据库的JDBC驱动程序编写查询。AddBatch用于“删除”/“插入”/“更新”语句,而不是“选择”语句。请参阅: 此列表可能包含用于更新、插入或删除行的语句;它还可能包含DDL语句,如CREATETABLE和DROP TABLE。但是,它不能包含将生成ResultSet对象的语句,例如SELECT语句。换句话说,列表只能包含生成更新计数的语句 创建时与语句对象关联的列表最初为空。您可以使用addBatch方法将SQL命令添加到此列表中
JDBC不允许创建批处理的SELECT查询,在我看来这是一个令人沮丧的限制,特别是因为准备好的语句不允许您指定可变数量的参数,比如in。。。条款 JavaRanch的文章F.J链接到建议通过创建一系列固定大小的查询并连接它们的结果来模拟批处理,这对我来说似乎是一个麻烦且次优的解决方案;现在必须手动构造和处理多个查询,并多次访问数据库。如果为手动定义的批选择的数字很差,那么您可能只为了回答一个简单的查询而多次访问数据库 相反,我开始使用所需的字段数量动态构造PreparedStatement对象。这确实意味着,与手动批处理相比,我们可能会创建更多的PreparedStatements,但我们限制了访问数据库的频率,并简化了实现,我认为这两者都是一个更重要的问题
/**
* 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的安全性,并避免了不必要的数据库命中。正如在其他答案中指出的那样,JDBC批量更新不适用于选择查询,或者至少不打算用于选择查询
然而,由于问题提到DB2是RDBMS,我认为值得在这里指出,尽管现在有点晚了…,这个特定数据库的官方驱动程序实际上使用DB2PreparedStatementexecuteDB2QueryBatch提供了这个特性,有关详细信息,请参阅。我不知道还有任何其他JDBC驱动程序具有此功能。@a_horse_和_no_name我宁愿链接到参考资料实际上,教程没有权威性,其中一些包含惊人的错误。但在我分配给这项任务的45秒内,我找不到一份关于这个问题的像样的陈述。@jmunch对我很有用。@Laurel我没有写“文档”,我在这里的评论几年来已经清楚地表明,这不是文档,只是一个教程。我不喜欢让人把话塞进我的嘴里。这个来自JavaRanch的旧版本提供了几个选项:您能详细说明为什么您更喜欢使用批处理语句而不是IN子句吗?如果我们不使用JDBC,我们会写一个IN查询,不是吗?JDBC使用不同的模式有什么好处?我通常不是番石榴的超级粉丝,因为理论上它似乎都很有用,但我发现它在实践中的用途非常有限。不过,我确实喜欢你在这里使用它的方式。你错过了;番石榴可以制作很多非常有用的图案。它引入的许多技术都被合并到Java8中的JDK中,但是Guava还提供了很多其他整洁的工具。我鼓励你再看一眼。