В настоящее время я пытаюсь реализовать следующий запрос sql в jooq:
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 функция, объединяющая две карты.
This подход работает. Однако я хотел бы выполнить всю обработку на сервере базы данных, как предполагает первый запрос.
Я попытался использовать подпрограмму, сгенерированную 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 использовать исходное значение в слиянии, как в необработанном запросе SQL с t.hstore_data?