说我有一个表格查询
SELECT * FROM MYTABLE WHERE MYCOL in (?)
我想将参数参数化为 in。
有没有一种直接的方法可以在 Java 中使用 JDBC 执行此操作,并且可以在不修改 SQL 本身的情况下在多个数据库上工作?
最近的question I've found had to do with 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 个项目有此限制。
关于java - 使用 JDBC 参数化 IN 子句的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2861230/