【问题标题】:Howto return ids on Inserts with Ibatis ( with RETURNING keyword )如何使用 Mybatis 返回插入的 ids(使用 RETURNING 关键字)
【发布时间】:2010-12-18 16:30:17
【问题描述】:

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

目前我使用以下 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>

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

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

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

那么问题来了:

如何在 ibatis 中使用上述语句?

【问题讨论】:

    标签: java postgresql ibatis


    【解决方案1】:

    &lt;selectKey&gt; 元素是&lt;insert&gt; 元素的子元素,其内容在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 序列中选择的密钥。

    【讨论】:

    • 这个解决方案解决了我的并发问题。如果 ibatis 可以使用 INSERT INTO .. RETUING .. 语法,它只会留下问题。
    【解决方案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 开发人员隐藏)。

    【讨论】:

    • 这将是我正在寻找的答案......但它不起作用:使用 executer.queryForObject 时返回 id,但没有插入任何内容,当我使用 executer.insert 时已插入,但返回 null
    • 这很奇怪,因为我复制并粘贴了我的工作代码。我也不明白 - 你怎么能在不添加新记录的情况下获得 id?您在 iBatis SQL 日志中看到了什么?
    • 听起来你们中的一个启用了自动提交,而另一个没有。
    猜你喜欢
    • 1970-01-01
    • 2021-07-11
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 2018-04-18
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多