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

  • 相关阅读:
    OC与Swift的区别二(常量、变量、运算符)
    OC与Swift的区别一(文件结构)
    OC对象的归档及解档浅析
    OC单例模式的实现
    oc文件基本读写及操作
    IOS之沙盒(Sandbox)机制
    IOS开发之KVC与KVO简述
    SpringMVC控制器配置文件
    spring常用的连接池属性文件配置
    Struts2文件上传方式与上传失败解决方式
  • 原文地址:https://www.cnblogs.com/wggj/p/12470437.html
Copyright © 2020-2023  润新知