Jdbc 如何使用不同数量的参数构建一个准备好的语句?

Jdbc 如何使用不同数量的参数构建一个准备好的语句?,jdbc,prepared-statement,derby,Jdbc,Prepared Statement,Derby,我用了很多选择。。。从…起哪里在我的应用程序中(…),每次我都会生成一个PreparedStatement,例如 public List<String> getUsernames(int[] ids) { String sql = "SELECT username FROM user WHERE id IN (" + String.join(", ", Collections.nCopies(ids.length, "?") + ")"; try (PreparedS

我用了很多<代码>选择。。。从…起哪里在我的应用程序中(…),每次我都会生成一个
PreparedStatement
,例如

public List<String> getUsernames(int[] ids) {
    String sql = "SELECT username FROM user WHERE id IN (" + String.join(", ", Collections.nCopies(ids.length, "?") + ")";
    try (PreparedStatement ps = conn.prepareStatement(sql)) {
        for (int i = 0; i < ids.length; i ++) {
            ps.setInt(i + 1, ids[i]);
        }
        ResultSet rs = ps.executeQuery();
        ...
    }
    ...
}

应具有相同的查询计划,只需缓存一次。

< P>可以考虑仅用固定参数(1024)保持绑定参数的单个准备语句。然后,只需绑定实际拥有的值,并将第一个参数绑定到其他未使用的占位符

public List<String> getUsernames(int[] ids) {

if (ids = null || ids.length < 1 || ids.length > 1024) return null;         int NUM_PARAMS = 1024;
    String sql = "SELECT username FROM user WHERE id IN (" + String.join(", ", Collections.nCopies(NUM_PARAMS, "?") + ")";
    try (PreparedStatement ps = conn.prepareStatement(sql)) {
        for (int i=0; i < ids.length; i ++) {
            ps.setInt(i + 1, ids[i]);
        }
        for (int i=ids.length; i < NUM_PARAMS; i ++) {
            ps.setInt(i + 1, ids[0]);
        }

        ResultSet rs = ps.executeQuery();
        // ...
    }
    // ...
}
如果您传入
(2,3)
作为可能的值,我的代码将生成以下
,其中位于

WHERE id IN (2, 3, 2, 2, 2);
                   ^^^^^^^ dummy values 

用传入的另一个值回填剩余的
没有问题,这样做不会改变查询的逻辑结果。

我最近使用了apache derby,derby将为每个preparedstatement生成类,因此我的应用程序有时可能会因元数据空间不足而崩溃。让我试试,如果ApacheDerby支持
id=any(?)
您知道
WHERE in
子句中的最大参数数是多少吗?顺便说一句,我的应用程序中的另一个问题是批量插入:
插入到表中(col1,col2,col3)值(?,,,,(,,,?,,,,,…
。有什么方法可以简化这个预先准备好的语句吗?我不知道使用JDBC有什么比较干净的方法可以做到这一点。如果您热衷于使用JPA/Hibernate,本地查询可以接受绑定参数的集合。@TimBiegeleisen,从1到1024。如果条件列表大于1024,我将把它们分成许多查询。这个解决方案可能在
SELECT。。。在(…)
情况下。但是如何处理这种情况:
INSERT-INTO-table(col1,col2,col3)VALUES(?,,?),(,,,?,?),…
老实说,
VALUES
子句的存在意味着所有这些数据都有一个源,例如在CSV文件中。我建议您使用SQL数据库的大容量加载功能,一次快速引入许多数据记录。所以,我对你的第二点的回答是,我甚至没有必要这么做。不是这个情况。我的应用程序是关于实时数据收集的。不过,这并不重要,我相信数据库引擎优化INSERT所需的资源比优化SELECT要少得多。
SELECT username FROM user WHERE id IN (?,?,?,?,?);
WHERE id IN (2, 3, 2, 2, 2);
                   ^^^^^^^ dummy values