zoukankan      html  css  js  c++  java
  • 一种用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操作符来实现,原理其实是一样的。限于篇幅,本文不再展开。

  • 相关阅读:
    已经有人提出过循环
    中华术数系列之奇门遁甲精简版
    研究下市场上有哪些软件项目/产品,哪些是值得做的?
    中华术数系列之奇门遁甲手机版
    Webbrowser代理支持
    随笔:杂念纷呈
    架构设计实践:基于WCF大型分布式系统(转)
    WCF分布式开发必备知识(3):Enterpise Services(转)
    看完这20部电影 你能变成经济学大师(转)
    WCF服务契约继承与分解设计(转)
  • 原文地址:https://www.cnblogs.com/wggj/p/12470437.html
Copyright © 2011-2022 走看看