要查询PostgreSQL 10.11数据库,我使用的是jOOQ 3.12.4,它与Spring Boot 2.2捆绑在一起。
假设我已经使用jOOQ建立了这样的查询:
final String[] ids = ...;
final var query = dslContext.selectFrom(MY_TABLE).where(MY_TABLE.ID.in(ids));
final Map<String, List<MyTable>> changeDomains = query.fetch().intoGroups(MY_TABLE.ID, MyTable.class);
这段代码可以正常运行并产生预期的结果。但是,当我重构查询并引入一个命名参数(以便在代码的多个部分重用查询)时,如下所示:
final String[] ids = ...;
final var query = dslContext.selectFrom(MY_TABLE).where(MY_TABLE.ID.in(param("ids")));
final Map<String, List<MyTable>> changeDomains = query.bind("ids", ids).fetch().intoGroups(MY_TABLE.ID, MyTable.class);
我突然开始出现以下错误:
org.springframework.jdbc.BadSqlGrammarException: jOOQ; bad SQL grammar ...; nested exception is org.postgresql.util.PSQLException: ERROR: operator does not exist: text = character varying[]
Hinweis: No operator matches the given name and argument type(s). You might need to add explicit type casts.
编辑:我使用时遇到相同的错误
MY_TABLE.ID.in(param("ids", String[].class))
代替。
我该如何解决或解决此问题?
但是当我重构查询并引入一个命名参数(以便在代码的多个部分重用查询)时
虽然您可以通过这种方式使用jOOQ(请注意,以非线程安全的方式更改和重用jOOQ查询时要小心!),但通常建议您以更实用的方式使用jOOQ,请参见:
重复使用jOOQ查询不会带来太多收益,特别是几乎没有任何性能提升。
因此,代替此:
final var query = dslContext.selectFrom(MY_TABLE)
.where(MY_TABLE.ID.in(param("ids")));
final Map<String, List<MyTable>> changeDomains = query
.bind("ids", ids).fetch().intoGroups(MY_TABLE.ID, MyTable.class);
这样写:
public ResultQuery<MyTableRecord> query(String[] ids) {
return dslContext.selectFrom(MY_TABLE).where(MY_TABLE.ID.in(ids));
}
// And then:
final Map<String, List<MyTable>> changeDomains = query(ids)
.fetch().intoGroups(MY_TABLE.ID, MyTable.class);
jOOQ,JDBC和SQL不支持单个绑定值IN
列表。虽然写这个似乎很有用:
SELECT * FROM t WHERE c IN (:bind_value)
并将数组或列表作为单个绑定值传递,SQL不支持此功能。某些API可能假装支持此功能(但在幕后将单个绑定值替换为多个?, ?, ..., ?
PostgreSQL支持= ANY (:bind_value)
数组运算符
SELECT * FROM t WHERE c = ANY (:bind_value)
您可以使用在jOOQ中使用它
dslContext.selectFrom(MY_TABLE).where(MY_TABLE.ID.eq(any(ids)));
这样,您可以bind()
在执行之前调用该方法来替换数组。但是,我仍然建议您编写动态返回查询的函数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句