MyBatisでデータ挿入後の自動採番IDを取得する方法

データベースにレコードを挿入した後に、その自動採番された主キーIDを取得したいケースはよくあります。MyBatisでは、この要件をuseGeneratedKeys属性または<selectKey>要素を使って実現できます。

useGeneratedKeysによるID取得

最もシンプルな方法は、<insert>タグにuseGeneratedKeys="true"keyPropertyを指定することです。

<insert id="insertStudent" useGeneratedKeys="true" keyProperty="id" parameterType="Student">
    INSERT INTO student(name, age, score) VALUES(#{name}, #{age}, #{score})
</insert>

この設定により、挿入後に生成されたIDが、渡されたオブジェクトのidフィールドに自動的にセットされます。ただし、対応するエンティティクラスにはsetId()およびgetId()メソッドが必須です。

<selectKey>によるID取得

別のアプローチとして、<selectKey>要素を使用して明示的にIDをクエリすることも可能です。これは特に、データベースが自動採番をサポートしていない場合や、カスタムロジックでIDを生成する際に有用です。

<insert id="insertStudent" parameterType="Student">
    INSERT INTO student(name, age, score) VALUES(#{name}, #{age}, #{score})
    <selectKey keyProperty="id" resultType="int" order="AFTER">
        SELECT LAST_INSERT_ID()
    </selectKey>
</insert>

ここで注意すべき点:

  • order="AFTER"はINSERT実行後にSELECTを実行することを意味します。
  • LAST_INSERT_ID()はMySQL専用の関数であり、直前に挿入されたレコードの自動採番IDを返します。
  • Oracleなどの他のDBでは、シーケンスを使用するなど異なるSQLが必要になります。

戻り値について

MyBatisのinsert操作の戻り値は、影響を受けた行数(通常は1)です。ID自体は戻り値ではなく、引数として渡したオブジェクトに直接セットされます。

Student student = new Student("example", 20, 90);
System.out.println("Before: " + student.getId()); // null or 0
studentMapper.insertStudent(student);
System.out.println("After: " + student.getId());  // 自動採番されたID

補足:MySQL接続時の注意点

MySQL 8.xを使用する際は、JDBC URL内の特殊文字をXMLで正しくエスケープする必要があります。

<property name="url" 
          value="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8&amp;serverTimezone=UTC"/>

また、依存ライブラリとして最新のMySQLコネクタを指定することが推奨されます。

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.21</version>
</dependency>

タグ: MyBatis MySQL 自動採番ID Java ORM

8月6日 06:40 投稿