我配置了一个看起来像这样的语句(这里解释一下,我面前没有实际的代码):
<insert id="createRecord" parameterType="map">
INSERT INTO MYTABLE (id, name, creator, description)
VALUES (#{id}, #{name}, #{creator}, #{description})
ON CONFLICT ON CONSTRAINT (name, creator)
DO UPDATE SET
name = #{name},
creator = #{creator},
description = #{description}
</insert>
就目前而言,应用程序代码通过调用 mybatis/postgres 来生成
id
本身以获取下一个序列值,然后将其传递给 createRecord
。
我想重构这段代码,以便在
id
中创建 createRecord
。 据我所知,一种方法是将语句中的 #{id}
替换为 nextval('my_seq')
。 另一种方法是使用 selectKey
:
<insert id="createRecord" parameterType="map">
<selectKey keyProperty="id" resultType="long">
select nextval('my_seq')
</selectKey>
INSERT INTO MYTABLE (id, name, creator, description)
VALUES (#{id}, #{name}, #{creator}, #{description})
ON CONFLICT ON CONSTRAINT (name, creator)
DO UPDATE SET
name = #{name},
creator = #{creator},
description = #{description}
</insert>
我希望在这两种情况下都能够获取 id 的值作为返回值;无论是新记录并生成新的序列 id,还是存在冲突/更新,现有 id。 我怎样才能做到这一点?
如果您像这样重写查询,则可以返回 id:
<select id="createRecord" parameterType="map" resultType="long" flushCache="true">
INSERT INTO MYTABLE (id, name, creator, description)
VALUES (nextval('my_seq'), #{name}, #{creator}, #{description})
ON CONFLICT ON CONSTRAINT (name, creator)
DO UPDATE SET
name = #{name},
creator = #{creator},
description = #{description}
RETURNING id
</insert>
此查询现在看起来像一个选择查询,它返回一个结果,并且应该映射为常规选择查询(但应该使用
flushCache
,因为它不是只读查询)。