Java 使用jooq使用hstore merge创建重复密钥

Java 使用jooq使用hstore merge创建重复密钥,java,sql,postgresql,jooq,Java,Sql,Postgresql,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) RE

目前,我正在尝试在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 $1 || $2;'
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(".*"));
types.add(新的ForcedType()
.withUserType(“java.util.Map”)
.具有约束力(“HStoreStringBinding”)
.withIncludeExpression(“.*U数据”)
。包括类型(“.”);
添加(新的ForcedType()
.withUserType(“java.util.Map”)
.具有约束力(“HStoreLongBinding”)
.withIncludeExpression(“.*u计数”)
。包括类型(“.”);
绑定适用于hstores,但不适用于自定义函数

  • 还有更聪明的方法吗
  • add()键入不正确的原因可能是什么
  • 我如何告诉jooq在合并中使用原始值,就像在原始SQL查询中使用t.hstore_数据一样 add()键入不正确的原因可能是什么

    尝试命名函数参数,否则无法将其与
    includeExpression
    属性匹配。要匹配函数的返回值,请将函数名本身用作
    includeExpression
    。当然,您可以不使用属性,将所有
    hstore
    类型与更通用的绑定进行匹配:

    types.add(新的ForcedType()
    .withUserType(“java.util.Map”)
    .具有约束力(“HStoreStringBinding”)
    。包括类型(“hstore”);
    
    我如何告诉jooq在合并中使用原始值,就像在原始SQL查询中使用t.hstore_数据一样

    代码生成工作完成后,只需使用add函数,就像在语句的SQL版本中一样:

    set(TABLE.HSTORE_数据,例程.add(TABLE.HSTORE_数据,TABLE.getHstoreData()))
    
    不相关,但是:实际上不需要定义自己的
    add()
    函数。您只需使用hstore的
    hs|u concat()
    ,这是
    |
    运算符的实现。@a_horse_没有名字的确,我曾经想过尝试一下,但又忘了。谢谢这似乎管用,谢谢!我只需要交换强制类型的顺序,还有一件事:当我应用您对集合(…)的建议时,参数冲突。TABLE.HSTORE_数据是一条记录,而函数需要map@fabianski:“我还需要交换强制类型的顺序”-第一个匹配适用。“TABLE.HSTORE_数据是一条记录”-为什么它现在是一条记录?您已将第一个强制类型应用于所有
    “*\u data”
    列。你改变了吗?啊,是的,我一定改变了什么,因为我想试着离开这里。然而,这造成了错误,因为地图在某些地方是必要的。因此,要匹配函数的返回值,请将函数名本身用作includeExpression。我了解如何使用includeexpression(“.*u data | add”)执行类似的操作。你是那个意思吗?因为它仍然与类型不匹配:(@fabianski:
    Map
    Map
    在Java中是不兼容的类型。这听起来像是一个新问题,有额外的信息,为什么你首先需要
    Map
    。是的,你说得对。在这个地方我不需要Map。但是在其他地方,我在一个对象中存储不同标记的计数。使用Map而不是Map,很容易这就是为什么我在*_数据和*_计数之间有所不同