如何使用Ibatis返回插入ID(使用RETURNING关键字)

时间:2009-11-20 10:47:52

标签: java postgresql ibatis

我正在使用iBatis / Java和Postgres 8.3。 当我在ibatis中插入时,我需要返回id 我用下表来描述我的问题:
CREATE TABLE sometable ( id serial NOT NULL, somefield VARCHAR(10) );
通过运行create语句自动生成序列sometable_id_seq

目前我使用以下sql map:

<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>

这似乎是ibatis检索新插入的id的方法。 Ibatis首先运行INSERT语句,然后询问序列的最后一个id 我怀疑这将适用于许多并发插入。 (discussed in this question

我想在ibatis中使用以下声明:
INSERT INTO sometable ( somefield ) VALUES ( #value# ) RETURNING id;

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

所以问题出现了:

我如何在ibatis上使用上述声明?

2 个答案:

答案 0 :(得分:15)

<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序列中选择的密钥。

答案 1 :(得分:9)

这是一个简单的例子:

<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开发人员隐藏的内容)。