为了查询postgresql10.11数据库,我使用了jooq3.12.4,它与springboot2.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))
相反。
如何解决或解决这个问题?
1条答案
按热度按时间vd2z7a6w1#
更好的代码重用解决方案
但是当我重构查询并引入一个命名参数时(在代码的多个部分中重用查询)
虽然您可以这样使用jooq(在以非线程安全的方式变异和重用jooq查询时要小心!),通常建议以更实用的方式使用jooq,例如:
https://blog.jooq.org/2017/01/16/a-functional-programming-approach-to-dynamic-sql-with-jooq/
https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql/
通过重新使用jooq查询,您不会获得太多好处,特别是,几乎没有任何性能提升。
所以,与其这样:
写下:
您遇到的实际问题:
jooq、jdbc和sql不支持单绑定值
IN
列表。虽然这样写似乎很有用:而将数组或列表作为单个绑定值传递,这在sql中是不受支持的。有些api可能会假装支持这个功能(但在幕后,它会将单个绑定值替换为多个绑定值)
?, ?, ..., ?
postgresql支持= ANY (:bind_value)
带数组的运算符你可以在jooq中使用
那样的话,你可以打电话给
bind()
方法在执行之前替换数组。但是,我仍然建议您编写动态返回查询的函数。