PreparedStatement.addBatch()可用于SELECT查询吗?
想象一下,我有100个SELECT查询,这些查询因一个输入而不同。 PreparedStatement可用于该值。
我在Web上看到的所有文档都是批量插入/更新/删除。 我从未见过用于select语句的批处理。
可以这样做吗? 如果是这样,请在下面的示例代码中帮助我。
我想这可以使用“IN”子句来完成,但我更喜欢使用批处理的select语句。
示例代码:
public void run(连接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(); } //我在这里打电话给什么? int [] result_array = pstmt.executeBatch() while(pstmt.getMoreResults()){ ResultSet result_set = pstmt.getResultSet(); //在这里工作 } }
我想这也可能是依赖于驱动程序的行为。 我正在使用他们的JDBC驱动程序编写针对IBM AS / 400 DB2数据库的查询。
查看文档 :
该列表可能包含更新,插入或删除行的语句; 它还可能包含DDL语句,如CREATE TABLE和DROP TABLE。 但是,它不能包含将生成ResultSet对象的语句,例如SELECT语句。 换句话说,列表只能包含产生更新计数的语句。
该列表在创建时与Statement对象关联,最初为空。 您可以使用addBatch方法将SQL命令添加到此列表中。
AddBatch()用于’delete’/’insert’/’update’语句,而不是’select’语句。
JDBC不允许创建批处理的SELECT
查询,在我看来这是一个令人沮丧的限制,特别是因为预处理语句不允许您指定可变数量的参数,如IN (...)
子句。
JavaRanch文章FJ链接建议通过创建一系列固定大小的查询并加入他们的结果来模拟批处理,这对我来说似乎是一个麻烦且次优的修复; 你必须现在手动构建和处理多个查询,并多次点击数据库。 如果为手动定义的批次选择的数字很差,您最终可能会多次访问数据库以回答简单的查询。
相反,我已经采用我需要的字段数来动态构建PreparedStatement
对象。 这确实意味着我们可能创建比手动批处理更多的PreparedStatement
,但是我们限制了我们访问数据库的频率并简化了我们的实现,我认为这两者都是一个更重要的问题。
/** * Use this method to create batch-able queries, eg: * "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 find(Connection conn, List words) throws SQLException { Set 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
的安全性,并避免不必要的数据库命中。