1 回答
TA贡献1797条经验 获得超6个赞
从 jOOQ 3.14.0 开始
该JSON_OBJECTAGG
聚合函数是在本机现在jOOQ支持:
DSL.jsonObjectAgg(TABLE.NAME, TABLE.VALUE).filterWhere(TABLE.NAME.isNotNull());
FILTER
在 jOOQ 3.14.8 中添加了对子句的支持。
从 jOOQ 3.14.8 和 3.15.0 开始
如果 jOOQ 没有实现特定的聚合函数,您现在可以指定DSL.aggregate()
使用自定义聚合函数。
DSL.aggregate("json_object_agg", SQLDataType.JSON, TABLE.NAME, TABLE.VALUE) .filterWhere(TABLE.NAME.isNotNull());
这是通过https://github.com/jOOQ/jOOQ/issues/1729实现的
对于 jOOQ 3.14.0
jOOQ DSL
API 中缺少一个功能,即创建纯 SQL 聚合函数。这还不可用的原因(从 jOOQ 3.11 开始)是因为有很多微妙的内部结构来指定支持所有供应商特定选项的供应商不可知聚合函数,包括:
FILTER (WHERE ...)
条款(如您在问题中提到的),必须使用CASE
OVER (...)
子句将聚合函数转换为窗口函数WITHIN GROUP (ORDER BY ...)
支持有序集合聚合函数的子句DISTINCT
条款,如果支持其他特定于供应商的聚合函数扩展
在您的特定情况下,简单的解决方法是一直使用纯 SQL 模板,正如您在问题中提到的:
DSL.field("COALESCE(jsonb_object_agg({0}, ({1})) FILTER (WHERE {0} IS NOT NULL), '{}')::jsonb", JSON_TYPE, key, select)
或者你做你之前提到的事情。关于这种担忧:
...但我随后遇到了我的 T 类型为 JsonNode 的问题,其中 DSL#coalesce 似乎将我的 coalesceTo 转换为 varchar。
那可能是因为您使用了agg.getType()
which returnsClass<?>
而不是agg.getDataType()
which returns DataType<?>
。
但这将是最后的手段:感觉就像我离让用户将他们想要的任何 SQL 注入我的数据库仅一步之遥
我不确定为什么这是一个问题。您仍然可以自己控制普通 SQL API 的使用,用户将无法注入任意内容key
,select
因为您也控制这些元素。
添加回答
举报