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にシーケンスが欲しいなあ。