web-dev-qa-db-ja.com

Ibatisを使用したインサートでIDを返す方法(RETURNINGキーワードを使用)

私はiBatis/JavaとPostgres8.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>
_

これは、新しく挿入されたIDを取得するためのibatisの方法のようです。 Ibatisは最初にINSERTステートメントを実行し、その後、シーケンスに最後のIDを要求します。
これが多くの同時挿入で機能するかどうかは疑問です。 ( この質問で説明

Ibatisで次のステートメントを使用したいと思います。
INSERT INTO sometable ( somefield ) VALUES ( #value# ) RETURNING id;

しかし、_<insert>_ sqlMap ibatis内で使用しようとすると、IDが返されません。 _<selectKey>_タグが必要なようです。

だからここに質問が来ます:

上記のステートメントをibatisで使用するにはどうすればよいですか?

14
Christoph

<selectKey>要素は<insert>要素の子であり、その内容はメインのINSERTの前に実行されますステートメント。 2つのアプローチを使用できます。

レコードを挿入した後にキーを取得します

このアプローチは、ドライバーによって異なります。これにはスレッド化が問題になる可能性があります。

レコードを挿入する前にキーを取得する

このアプローチはスレッドの問題を回避しますが、より多くの作業が必要です。例:

<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シーケンスから選択されたキーが得られます。

15
lutz

簡単な例を次に示します。

<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開発者から隠されているもの)を知ることを要求していません。
9
leonidv