MyBatisでテーブルにデータをInsertした際に、DBのほうで自動採番されたPrimary Keyを取得する方法です。

目次

環境

  • JDK 12 (OpenJDK)
  • MyBatis 3.5.1
  • MySQL 8.0.15

データベースはDockerでMySQLの環境構築で作成したものを使用します。

プロジェクトの生成とMyBatisの設定

プロジェクトやMyBatisの設定は、MyBatisでMySQLに接続するで作成したものを使います。

Mapper XMLファイル

CityMapper.xmlにinsert文を追加します。userGeneratedKeysにtrueを設定すると、データがinsertされた後、keyPropertyで指定したフィールドに自動採番されたPrimary Keyがセットされます。

<insert id="insertCity" useGeneratedKeys="true" keyProperty="ID">>
  insert into city (Name, CountryCode, District, Population)
  values (#{name}, #{countryCode}, #{district}, #{population})
</insert>

Mapperクラス

XMLファイルに追加したinsertCityと対応するメソッドをCityMapper.javaに追加します。

package learning.mybatis.data;

import learning.mybatis.model.City;

public interface CityMapper {

  public City selectCity(int ID);

  // 追加
  public int insertCity(City city);
}

実行クラスの作成

実行用のクラスです。テーブルにデータをinsertした後、自動採番されたIDを使って、追加されたデータをselectします。

package learning.mybatis;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import learning.mybatis.data.CityMapper;
import learning.mybatis.model.City;

public class AutoIncrementApp {

  public static void main (String[] args) {
    try {
      InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      SqlSession session = sqlSessionFactory.openSession();

      CityMapper mapper = session.getMapper(CityMapper.class);
      
      // insert文のパラメーターとして渡すオブジェクトを生成
      City city = new City();
      city.name = "foo";
      city.countryCode = "JPN";
      city.district = "bar";
      city.population = 123456;

      mapper.insertCity(city);
      System.out.println("New City ID: " + city.ID);

      // 取得したPrimary Keyを使ってselect
      City result = mapper.selectCity(city.ID);
      System.out.println("City [ID=" + result.ID + ", Name=" + result.name + 
              ", CountryCode=" + result.countryCode + ", District=" + result.district + 
              ", Population=" + result.population + "]");

      session.commit();
      session.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

実行

実行前に最後尾のIDを確認しておきます。

mysql> select * from city order by ID desc LIMIT 3;
+------+----------+-------------+------------+------------+
| ID   | Name     | CountryCode | District   | Population |
+------+----------+-------------+------------+------------+
| 4079 | Rafah    | PSE         | Rafah      |      92020 |
| 4078 | Nablus   | PSE         | Nablus     |     100231 |
| 4077 | Jabaliya | PSE         | North Gaza |     113901 |
+------+----------+-------------+------------+------------+

実行するとコンソールに以下のように出力されます。(一度失敗したのでIDが2つ増えてます)

New City ID: 4081
City [ID=4081, Name=foo, CountryCode=JPN, District=bar, Population=123456]

テーブルを直接参照しても、新しくデータが追加されたことを確認できます。

mysql> select * from city order by ID desc LIMIT 3;
+------+--------+-------------+----------+------------+
| ID   | Name   | CountryCode | District | Population |
+------+--------+-------------+----------+------------+
| 4081 | foo    | JPN         | bar      |     123456 |
| 4079 | Rafah  | PSE         | Rafah    |      92020 |
| 4078 | Nablus | PSE         | Nablus   |     100231 |
+------+--------+-------------+----------+------------+