一種用JDBC實現批量查詢的巧妙方法


一、問題提出

眾所周知,JDBC的批量操作接口(addBatch)不接受Select語句,也沒有提供其它內建的接口。若想實現JDBC批量查詢,不得不依靠自己想辦法。

批量查詢中最常見的查詢條件是“=”判斷,對此,通用方法是將WHERE子句中的“=”改為“IN (?, ?, ...)”。但這帶來另一個問題,即綁定變量的數量不確定。

二、解決思路

通過度娘得知,很多帖子建議構造多個PreparedStatement,而它們的WHERE子句中包含數量不同的“?”,根據運行情況選擇合適的PreparedStatement執行。

實話實說,此方法雖然可解決問題,但顯得過於復雜,能不能用一個PreparedStatement就解決問題?

答案是可以,訣竅在於:IN 操作符的實際綁定值,既可以是重復的值,也可以是實際上不存在的值。

三、示例代碼

以下是自己在實際項目中編寫的代碼:

List<Long> IDs = ...;    // 查詢用的ID隊列
//每10個ID批量查詢一次
PreparedStatement ps = conn.prepareStatement("SELECT * FROM MY_TABLE WHERE ID IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?))";
int index = 0;  //ID的下標
int times = (IDs.size() - 1) / 10 + 1; //外循環次數 for (int i = 0; i < times; i++) { for (int j = 0; j < 10; j++) { // 如果不足10個(最后一次時)ID,以不可能的ID湊數 ps.setLong(j + 1, (index < IDs.size() ? IDs.get(index) : -j));
index ++; } rs
= ps.executeQuery(); while (rs.next()) { ... //處理rs } }

因為實際上不會存在ID為負數的情況,所以本例中超出實際范圍的綁定值設成了某個負數。

若不能確定某個值肯定不存在,則可用該批查詢中的某個值(比如最后一個ID)多次綁定。代碼修改很簡單,這里省略。

 四、進一步擴展

以上均是按“單一主鍵” 字段 + “等於判定”的形式討論的,實際上在“組合主鍵”/"非主鍵"字段、“范圍判定”/"like判定"/"常規表達式判定"的情況下,也一樣可以使用,僅僅是綁定值略有差異而已。

對於更復雜的情況,還可以用OR操作符來實現,原理其實是一樣的。限於篇幅,本文不再展開。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM