使用 jooq 在 hstore 合并的重复键上
On duplicate key with hstore merge using jooq
目前,我正在尝试在 jooq 中实现以下 sql 查询:
INSERT INTO table as t (id, hstore_data)
VALUES ('test', '"key1" => "val1"')
ON CONFLICT (id)
DO UPDATE SET hstore_data = add(t.hstore_data, '"keyX" => "valX"');
add()是一个自定义函数:
CREATE FUNCTION add(hstore, hstore) RETURNS hstore
AS 'select || ;'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
到目前为止,我设法解决了这个问题 运行:
return DSL.using(configuration)
.insertInto(TABLE)
.columns(TABLE.ID, TABLE.HSTORE_DATA)
.values(table.getId(), table.getHstoreData())
.onDuplicateKeyUpdate()
.set(TABLE.HSTORE_DATA,
merge(
DSL.using(configuration).select(TABLE.HSTORE_DATA).from(TABLE).where(TABLE.ID.eq(table.getId())).fetchAnyInto(HashMap.class)
, table.getHstoreData()
)
)
.execute();
merge() 是一个合并两个地图的简单 JAVA 函数。
这种方法有效。但是,我想按照第一个查询的建议在数据库服务器上进行所有处理。
我尝试使用 jooq 为 add() 生成的例程。但似乎 jooq 不使用 hstore 绑定。绑定在 ConfigGenerator 中定义如下:
types.add(new ForcedType()
.withUserType("java.util.Map<String, String>")
.withBinding("HStoreStringBinding")
.withIncludeExpression(".*_data")
.withIncludeTypes(".*"));
types.add(new ForcedType()
.withUserType("java.util.Map<String, Long>")
.withBinding("HStoreLongBinding")
.withIncludeExpression(".*_counts")
.withIncludeTypes(".*"));
绑定适用于 hstores,但不适用于自定义函数。
- 有没有更聪明的方法?
- add() 未正确输入的原因可能是什么?
- 如何告诉 jooq 在合并中使用原始值,就像我在使用 t.hstore_data 的原始 SQL 查询中所做的那样?
What might be the reason for add() not being correctly typed?
尝试命名您的函数参数,否则您无法将它们与 includeExpression
属性 匹配。要匹配函数的 return 值,请将函数名称本身用作 includeExpression
。当然,您可以只留下 属性,并使用更通用的绑定匹配所有 hstore
类型:
types.add(new ForcedType()
.withUserType("java.util.Map<String, String>")
.withBinding("HStoreStringBinding")
.withIncludeTypes("hstore"));
How can I tell jooq to use the original value in the merge as I do in the raw SQL query with t.hstore_data?
代码生成成功后,您只需使用添加函数,就像在 SQL 版本的语句中一样:
set(TABLE.HSTORE_DATA, Routines.add(TABLE.HSTORE_DATA, table.getHstoreData()))
目前,我正在尝试在 jooq 中实现以下 sql 查询:
INSERT INTO table as t (id, hstore_data)
VALUES ('test', '"key1" => "val1"')
ON CONFLICT (id)
DO UPDATE SET hstore_data = add(t.hstore_data, '"keyX" => "valX"');
add()是一个自定义函数:
CREATE FUNCTION add(hstore, hstore) RETURNS hstore
AS 'select || ;'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
到目前为止,我设法解决了这个问题 运行:
return DSL.using(configuration)
.insertInto(TABLE)
.columns(TABLE.ID, TABLE.HSTORE_DATA)
.values(table.getId(), table.getHstoreData())
.onDuplicateKeyUpdate()
.set(TABLE.HSTORE_DATA,
merge(
DSL.using(configuration).select(TABLE.HSTORE_DATA).from(TABLE).where(TABLE.ID.eq(table.getId())).fetchAnyInto(HashMap.class)
, table.getHstoreData()
)
)
.execute();
merge() 是一个合并两个地图的简单 JAVA 函数。
这种方法有效。但是,我想按照第一个查询的建议在数据库服务器上进行所有处理。
我尝试使用 jooq 为 add() 生成的例程。但似乎 jooq 不使用 hstore 绑定。绑定在 ConfigGenerator 中定义如下:
types.add(new ForcedType()
.withUserType("java.util.Map<String, String>")
.withBinding("HStoreStringBinding")
.withIncludeExpression(".*_data")
.withIncludeTypes(".*"));
types.add(new ForcedType()
.withUserType("java.util.Map<String, Long>")
.withBinding("HStoreLongBinding")
.withIncludeExpression(".*_counts")
.withIncludeTypes(".*"));
绑定适用于 hstores,但不适用于自定义函数。
- 有没有更聪明的方法?
- add() 未正确输入的原因可能是什么?
- 如何告诉 jooq 在合并中使用原始值,就像我在使用 t.hstore_data 的原始 SQL 查询中所做的那样?
What might be the reason for add() not being correctly typed?
尝试命名您的函数参数,否则您无法将它们与 includeExpression
属性 匹配。要匹配函数的 return 值,请将函数名称本身用作 includeExpression
。当然,您可以只留下 属性,并使用更通用的绑定匹配所有 hstore
类型:
types.add(new ForcedType()
.withUserType("java.util.Map<String, String>")
.withBinding("HStoreStringBinding")
.withIncludeTypes("hstore"));
How can I tell jooq to use the original value in the merge as I do in the raw SQL query with t.hstore_data?
代码生成成功后,您只需使用添加函数,就像在 SQL 版本的语句中一样:
set(TABLE.HSTORE_DATA, Routines.add(TABLE.HSTORE_DATA, table.getHstoreData()))