Mybatisでauto_incrementされた値を取得する方法
insertの戻り値で取得する方法があると思ってたんですが、mutableなクラスにセットさせる方法しかなかったです。 まずはIDをセットするためのクラスを作り
class GeneratedEmployeeId { var value: Int? = null fun setValue(v: Int) { value = v } fun convert(): EmployeeId { Objects.requireNonNull(value, "generated employee-id is null") return EmployeeId(value!!) } }
@SelectKeyを使って、引数に渡したGeneratedEmployeeIdにセットするように指定します。
@Mapper interface EmployeeTableMapper { /** * Insert register event to register_event table * * @param event */ @Insert(""" insert into employee_register_events ( first_name , last_name , salary ) values ( #{event.firstName} , #{event.lastName} , #{event.salary}) """) @SelectKey( statement = arrayOf("select @@IDENTITY"), before = false, resultType = Int::class, keyProperty = "genId.value", keyColumn = "id" ) fun insert(@Param("event") event: EmployeeRegisterEvent, @Param("genId") genId: GeneratedEmployeeId) }
テストしてみます。なんどもinsertを動かしたのでidは8まで払い出しています。
mysql> select * from employee_register_events; +----+------------+-----------+--------+ | id | first_name | last_name | salary | +----+------------+-----------+--------+ | 1 | shown | white | 200000 | | 2 | shown | white | 200000 | | 3 | shown | white | 200000 | | 4 | shown | white | 200000 | | 5 | shown | white | 200000 | | 6 | shown | white | 200000 | | 7 | shown | white | 200000 | | 8 | shown | white | 200000 | +----+------------+-----------+--------+ 8 rows in set (0.00 sec)
このテストはコケるはず(次に払い出される値は9なので)
@SpringBootTest class EmployeeTableMapperTest extends Specification { @Autowired private EmployeeTableMapper sut def "test"() { expect: def genId = new GeneratedEmployeeId() sut.insert(new EmployeeRegisterEvent("shown", "white", 200000), genId) genId.getValue() == 1 } }
想定通りこけてくれました。
Condition not satisfied: genId.getValue() == 1 | | | | 9 false work.doilux.dddsamplekotlin.ftth.hr.GeneratedEmployeeId@2233cac0 Expected :1 Actual :9
mutableなクラスを作るのは微妙なので、Oracle(ポスグレも?)ならシーケンスにselectかけて取り出した方がいいと思います。 MySQLの場合はシーケンスがないので、どうしてもImmutableにしたいなら採番テーブルを作るしかなさそう。 MySQLにシーケンスが欲しいなあ。