我正在使用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上使用上述声明?
答案 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);
这比使用更好: