我正在使用 Java + Spring + MyBatis + Postgresql。我有一个带有
JSONB
列的表,其中有一系列 BIGINT
(在 Java 中映射到 Long
),出于性能原因,我想使用 mapper.xml
相对内部的查询进行更新属性所属的实体。
假设我有以下元素:
table_a
:数据库表column_1
:类型为 table_a
的
JSONB
key_alpha
:与 column_1
值关联的
BIGINT
理想情况下,使用纯
psql
语法,我会执行以下操作来初始化此类值:
UPDATE table_a
SET column_1 = jsonb_set(column_1, '{key_alpha}', to_jsonb(0));
以及以下内容来增加它:
UPDATE table_a
SET column_1 = jsonb_set(column_1, '{key_alpha}', to_jsonb((column_1->>'key_alpha')::bigint + 1));
问题在于,这个语法看起来与 MyBatis
xml
映射器语法不兼容。我如何使用 MyBatis 或使用替代方法来实现此结果,同时记住我需要一种性能关键的方法?
更具体地说,如果我尝试在
mapper.xml
中使用此语法:
<if test="incrementCountAlpha != null">column_1 = jsonb_set(column_1, '{key_alpha}', to_jsonb((column_1->>'key_alpha')::bigint + #{incrementCount})),</if>
<if test="incrementCountBeta != null">column_1 = jsonb_set(column_1, '{key_beta}', to_jsonb((column_1->>'key_beta')::bigint + #{incrementCount})),</if>
我收到以下错误;
### Error updating database. Cause: org.postgresql.util.PSQLException: ERROR: multiple assignments to same column "column_1"
以下陈述应该可以实现您的目标。
<update id="updateColumn1">
update table_a set column_1 = column_1
<if test="incrementCountAlpha != null">
|| jsonb_build_object(
'key_alpha',
coalesce((column_1->>'key_alpha')::bigint, 0) + #{incrementCountAlpha})
</if>
<if test="incrementCountBeta != null">
|| jsonb_build_object(
'key_beta',
coalesce((column_1->>'key_beta')::bigint, 0) + #{incrementCountBeta})
</if>
</update>
如果目标字段保证预先初始化,则COALESCE
可能是不必要的。
这是一个可执行的演示项目:
https://github.com/harawata/mybatis-issues/tree/master/so-77490757