如何在带有 Ibatis 的 Inserts 上返回 id ( 使用 RETURN 关键字 )

2022-09-04 00:51:13

我使用的是iBatis/Java和Postgres 8.3。当我在ibatis中插入时,我需要返回id。
我使用下表来描述我的问题:

序列通过运行 create 语句自动生成。CREATE TABLE sometable ( id serial NOT NULL, somefield VARCHAR(10) );sometable_id_seq

目前,我使用以下sql映射:

<insert id="insertValue" parameterClass="string" >
 INSERT INTO sometable ( somefield ) VALUES ( #value# );
 <selectKey keyProperty="id" resultClass="int">
  SELECT last_value AS id FROM sometable_id_seq
 </selectKey>
</insert>

这似乎是检索新插入的id的ibatis方式。Ibatis 首先运行一个 INSERT 语句,然后它要求序列提供最后一个 id。
我怀疑这是否适用于许多并发插入。(在这个问题中讨论 )

我想将以下语句与 ibatis 一起使用:
INSERT INTO sometable ( somefield ) VALUES ( #value# ) RETURNING id;

但是当我尝试在sqlMap中使用它时,ibatis不会返回id。它似乎需要标签。<insert><selectKey>

所以问题来了:

如何将上述声明与伊巴蒂斯一起使用?


答案 1

元素是元素的子元素,其内容在 main 语句之前执行。您可以使用两种方法。<selectKey><insert>INSERT

插入记录后获取密钥

此方法的工作原理取决于您的驱动程序。线程处理可能是一个问题。

在插入记录之前获取密钥

这种方法避免了线程问题,但工作量更大。例:

<insert id="insert">
  <selectKey keyProperty="myId"
             resultClass="int">
    SELECT nextVal('my_id_seq')
  </selectKey>
  INSERT INTO my
    (myId, foo, bar)
  VALUES
    (#myId#, #foo#, #bar#)
</insert>

在Java方面,你可以做

Integer insertedId = (Integer) sqlMap.insert("insert", params)

这应该为您提供从序列中选择的密钥。my_id_seq


答案 2

下面是一个简单的示例:

<statement id="addObject"
        parameterClass="test.Object"
        resultClass="int">
        INSERT INTO objects(expression, meta, title,
        usersid)
        VALUES (#expression#, #meta#, #title#, #usersId#)
        RETURNING id
</statement>

在 Java 代码中:

Integer id = (Integer) executor.queryForObject("addObject", object);
object.setId(id);

这样比使用更好:

  1. 它更简单;
  2. 它没有要求知道序列名称(通常对postgresql开发人员隐藏的内容)。

推荐