概要
MyBatisのSQLはXMLに書いたりアノテーションに文字列で渡す方法があるが、SqlProviderを使う方法を試してみた。
これが一番好きかもしれない。
ちなみにSpringBoot(mybatis-spring-boot-starter)を利用している。
SqlProviderの使い方
クエリの種類に応じてProviderアノテーションが用意されている。
今回はInsertを例にする
- @InsertProvider
- @UpdateProvider
- @DeleteProvider
- @SelectProvider
@Mapper interface FooRepository { // メソッドにProviderのアノテーション付与 // 実SQLを提供するクラスとメソッド名を渡す @InsertProvider(type = MySqlBuilder::class, method = "insert") fun save(foo: Foo) // SQLの提供クラス // インナークラスにしているが、アウタークラスでもOK class MySqlBuilder { companion object { // MyBatis側で利用されるので、JvmStaticアノテーションを付与 @JvmStatic fun insert(foo: Foo): String = foo.run { // SQLの生成はMyBatisのSQLビルダークラスを使っている // が、極端な話文字列を返せばいいので究極好き勝手にSQLを書ける SQL().INSERT_INTO("foo") .VALUES("id", "#{id}") .VALUES("name", "#{name}") .VALUES("age", "#{age}") .toString() } } } }
動的なSQLの生成
MyBatisのSQLビルダークラスは動的にSQLの組み立ても可能である。
SqlProvider側でインターフェースと同じ引数を受け取れるので、必要に応じて処理を埋め込む。
SQLビルダーは無名クラスにして組み立てるようにする。
class MySqlBuilder { companion object { @JvmStatic fun insert(careType: CareType): String = careType.run { // 動的に組み立てる場合は無名クラスにする object : SQL() { init { INSERT_INTO("foo") VALUES("id", "#{id}") VALUES("name", "#{name}") // 処理を埋め込むことも可能 if (name.isEmpty()) { VALUES("name", "'default name'") } VALUES("age", "#{age}") } }.toString() } } }