PostgreSQL の CURVAL() や、LASTVAL() で、シーケンスから求められるものではなく、
UUID のような型で Primary Key を構成するテーブル挿入直後のキーを取得したい。
RETURNING を使う。
insert文の次の書式
INSERT INTO テーブル VALUES (...) RETURNING PKのID INTO last_id;
で INSERT文実行で求める。
例)UUID自動ランダム関数を DEFAULT に持つテーブル
CREATE TABLE public.taskitems ( id uuid NOT NULL DEFAULT gen_random_uuid(), task_name varchar(64) NOT NULL, CONSTRAINT pk_taskttems PRIMARY KEY (id) );
このテーブルへRETURNINGを使った書き方は、
INSERT INTO taskitems ( task_name ) values ( 'a-task' ) RETURNING id
mySQL のように、、
<insert id="addItem" parameterType="sample.dto.TaskItem"> インサート文 <selectKey order="AFTER" keyProperty="id" resultType="string"> SELECT LAST_INSERT_ID() </selectKey> </insert>
ができれば、insert 実行したパラメータObject に生成キーが返ってきたのだが、
PostgreSQL のこのケースでは不可能
<select> で書くことで、resultType を使えるようにして、、
<select id="insertItem" parameterType="sample.dto.TaskItem" resultType="string"> INSERT INTO taskitems ( task_name ) values ( #{taskName} ) RETURNING id </select>
mybatis の selectOne または、selectList の実行で RETURNING → resultType としてキーを求める
String id = getSqlSession().selectOne(bindId(SampleMapper.class, "insertItem"), itemtask);
bindId(SampleMapper.class, "insertItem") でmybatis mapperステートメント+識別子になるように用意しておく。
selectList は、バルクインサートの時に使用する。
<select id="insertMulti" parameterType="list" resultType="string"> INSERT INTO taskitems ( task_name ) values <foreach collection="list" item="e" separator=","> ( #{e.taskName} ) </foreach> RETURNING id </select>
呼び出しは以下のように。
List<String> idlist = getSqlSession().selectList(bindId(SampleMapper.class, "insertMulti"), tasklist);
idlist は、バルクインサートで挿入されたレコードの id が返ってくる。
こうして見ると、SQLMap.xml の <setlect> は、名称にとらわれずに、SQL実行へのパラメータを付与して
結果を受け取るというパターンに使用できる。
statementType="CALLABLE" で、ストアドプロシージャも呼び出せるのと繋がる。