当前位置: 首页 > 面试题库 >

Java 使用JDBC参数化IN子句的最佳方法是什么?

充星腾
2023-03-14
问题内容

说我有一个查询表格

SELECT * FROM MYTABLE WHERE MYCOL in (?)

我想参数化in。

有没有一种简单的方法可以在Java中使用JDBC进行操作,而该方法可以在多个数据库上运行而无需修改SQL本身?

我发现的最接近的问题与C#有关,我想知道Java / JDBC是否有所不同。


问题答案:

在JDBC中,确实没有直接的方法可以做到这一点。某些 JDBC驱动程序似乎支持PreparedStatement#setArray()该IN子句。我只是不确定那是哪个。

你可以仅使用带有String#join()和的辅助方法,并Collections#nCopies()为IN子句生成占位符,使用另一个辅助方法来使用设置循环中的所有值PreparedStatement#setObject()

public static String preparePlaceHolders(int length) {
    return String.join(",", Collections.nCopies(length, "?"));
}

public static void setValues(PreparedStatement preparedStatement, Object... values) throws SQLException {
    for (int i = 0; i < values.length; i++) {
        preparedStatement.setObject(i + 1, values[i]);
    }
}

使用方法如下:

private static final String SQL_FIND = "SELECT id, name, value FROM entity WHERE id IN (%s)";

public List<Entity> find(Set<Long> ids) throws SQLException {
    List<Entity> entities = new ArrayList<Entity>();
    String sql = String.format(SQL_FIND, preparePlaceHolders(ids.size()));

    try (
        Connection connection = dataSource.getConnection();
        PreparedStatement statement = connection.prepareStatement(sql);
    ) {
        setValues(statement, ids.toArray());

        try (ResultSet resultSet = statement.executeQuery()) {
            while (resultSet.next()) {
                entities.add(map(resultSet));
            }
        }
    }

    return entities;
}

private static Entity map(ResultSet resultSet) throws SQLException {
    Enitity entity = new Entity();
    entity.setId(resultSet.getLong("id"));
    entity.setName(resultSet.getString("name"));
    entity.setValue(resultSet.getInt("value"));
    return entity;
}

请注意,某些数据库在该IN子句中具有允许的值数量限制。例如,Oracle对1000个项目有此限制。



 类似资料:
  • 问题内容: 我该如何对包含一个IN带有可变数量的参数的子句的查询进行参数化(例如这样的查询)? 在此查询中,参数的数量可以在1到5之间的任何位置。 我不希望对此(或XML)使用专用的存储过程,但是如果有一些特定于SQL Server 2008的优雅方法,我可以接受。 问题答案: 这是我使用的一种quick-and-dirty的技术: 因此,这是C#代码: 两个警告: 表现很糟糕。LIKE “%…%

  • 我正在编写一个可序列化的类,它接受多个参数,包括一个函数: 存储在成员变量中,因此需要可序列化。如果分配给它们的类型是可序列化的,则Javalambda是可序列化的。如果使用lambda创建,那么确保在构造函数中传递的是可序列化的最佳方法是什么? > 创建一个可序列化函数,并使用该函数: 问题: 现在,

  • 问题内容: 我正在尝试确定通过JDBC ping数据库的最佳方法。“最好”是指快速且低开销。例如,我考虑过执行以下命令: 但是我相信DUAL表是特定于Oracle的,并且我需要一些更通用的东西。 请注意,它具有一个方法,但是javadoc指出该方法不能用于测试连接的有效性。 问题答案: 是的,那只能是Oracle,但是在JDBC中没有通用的方法可以做到这一点。 大多数连接池实现都有一个配置参数,您

  • 我需要从数据库中选择一百个参数,然后在d to返回它来创建一个excel文件。 我使用的是spring数据,我认为有两种解决方案: > 使用multiselect方法,然后在DTO中定义一个包含所有参数的构造函数(参数数大于100) 使用multiselect方法并将数组(Object[])映射到DTO= 请问你还有其他的想法吗? 谢谢。

  • 问题内容: 我用下面的代码。两者在我的应用程序中都运行良好。 情况1。 情况2 但是我有一些问题: 在性能方面哪个更好? 在哪种情况下,请选择案例2? 问题答案: 情况2在性能上是更好的BUT:它返回一个大小不变的List。意味着您不能在其中添加/删除元素: 返回由指定数组支持的 固定大小的 列表。(将返回的列表更改为“直写”到数组。)

  • 问题内容: 我有一个用Java编写的Web应用程序(Spring,Hibernate / JPA,Struts2),用户可以在其中上传图像并将其存储在文件系统中。我想缩放这些图像,以使它们具有一致的大小,以便在网站上显示。哪些库或内置函数将提供最佳结果?在做出决定时,我将考虑以下标准: 免费/开源(基本) 易于实施 结果质量 性能 可执行文件的大小 问题答案: 看一下Java Image I /