Version v5.0 of the documentation is no longer actively maintained. The site that you are currently viewing is an archived snapshot. For up-to-date documentation, see the latest version.
COMMANDクエリ
概要
COMMANDクエリはTEMPLATEクエリをベースにしています。
コマンドは、SQLテンプレートとパラメータを1つの単位として扱う機能です。クラスにorg.komapper.annotation.KomapperCommandアノテーションを付けてSQLテンプレートを定義し、クラスのプロパティにパラメータを定義します。SQLの結果をどのように処理するかは、特定のクラスを継承することで表現されます。
COMMANDクエリを使用するには、Gradleビルドスクリプトに次の依存関係宣言を含める必要があります。
val komapperVersion: String by project
dependencies {
implementation("org.komapper:komapper-template:$komapperVersion")
}
Note
すべての スターター は上記の設定を含んでいます。 したがって、Starterを使う場合には上記の設定は不要です。Note
komapper-templateモジュールは内部でリフレクションを使います。
コマンド
下記は、複数件を取得するコマンドの例です。
@KomapperCommand("""
select * from ADDRESS where street = /*street*/'test'
""")
class ListAddresses(val street: String): Many<Address>({ selectAsAddress() })
コマンドを定義しビルドを実行すると、QueryDslにexecuteという名前の拡張関数が生成されます。したがって、上記のコマンドは次のようにして実行できます。
val query: Query<List<Address>> = QueryDsl.execute(ListAddresses("STREET 10"))
コマンドは、fromTemplateやexecuteTemplateを使う方法に比べて、コンパイル時にSQLテンプレートを検証できるという利点があります。具体的には次のことが可能です。
- SQLテンプレートの構文上の誤りを検出できます。例えば、
/*%end*/が不足している場合コンパイルエラーとなります。 - 利用されていないパラメータを検出できます。利用されていないパラメータが見つかった場合は警告メッセージを出力します。なお、パラメータに
org.komapper.annotation.KomapperUnusedアノテーションを付与することで警告を抑制できます。 - パラメータの型やメンバを検証できます。例えば、String型の
nameがパラメータの場合、SQLテンプレート上で/* name.unknown */のように存在しないメンバにアクセスしようとするとコンパイルエラーとなります。
Note
コマンドのクラスは、トップレベルのクラス、ネストされたクラス、インナークラスとして定義できます。ローカルクラスとしては定義できません。コマンドには5つの種類があります。
- One
- Many
- Exec
- ExecReturnOne
- ExecReturnMany
One
1件を取得するコマンドはorg.komapper.core.Oneを継承します。
@KomapperCommand("""
select * from ADDRESS where address_id = /*id*/0
""")
class GetAddressById(val id: Int): One<Address?>({ selectAsAddress().singleOrNull() })
Oneの型パラメータには取得したい値の型を指定します。Oneのコンストラクタには、検索結果を処理するラムダ式を渡します。ラムダ式の中でできることは、fromTemplateで言及したselect関数やselectAsEntity関数と同じです。
上述の例では、Addressクラスに@KomapperProjetionが付与されていることを前提にしています。そのため、selectAsAddress関数を使って結果をAddressクラスに変換しています。
Many
複数件を取得するコマンドはorg.komapper.core.Manyを継承します。
@KomapperCommand("""
select * from ADDRESS where street = /*street*/'test'
""")
class ListAddresses(val street: String): Many<Address>({ selectAsAddress() })
Manyの型パラメータには取得したい1件を表現する型を指定します。Manyのコンストラクタには、検索結果を処理するラムダ式を渡します。ラムダ式の中でできることは、fromTemplateで言及したselect関数やselectAsEntity関数と同じです。
上述の例では、Addressクラスに@KomapperProjetionが付与されていることを前提にしています。そのため、selectAsAddress関数を使って結果をAddressクラスに変換しています。
Exec
更新系のDMLを実行するコマンドはorg.komapper.core.Execを継承します。
@KomapperCommand("""
update ADDRESS set street = /*street*/'' where address_id = /*id*/0
""")
class UpdateAddress(val id: Int, val street: String): Exec()
ExecReturnOne
更新系のDMLを実行し1件を返すコマンドはorg.komapper.core.ExecReturnOneを継承します。
@KomapperCommand("""
insert into ADDRESS
(address_id, street, version)
values
(/* id */0, /* street */'', /* version */1)
returning address_id, street, version
""")
class InsertAddressThenReturn(val id: Int, val street: String): ExecReturnOne<Address>({ selectAsAddress().single() })
ExecReturnOneの型パラメータやコンストラクタについては、Oneと同様です。
ExecReturnMany
更新系のDMLを実行し複数件を返すコマンドはorg.komapper.core.ExecReturnManyを継承します。
@KomapperCommand("""
update ADDRESS set street = /*street*/'' returning address_id, street, version
""")
class UpdateAddressThenReturn(val id: Int, val street: String): ExecReturnMany<Address>({ selectAsAddress() })
ExecReturnManyの型パラメータやコンストラクタについては、Manyと同様です。
パーシャル
パーシャルはSQLテンプレートの部品を再利用するための機能です。
パーシャルはorg.komapper.annotation.KomapperPartialアノテーションを注釈したクラスとして定義します。
@KomapperPartial(
"""
limit /* limit */0 offset /* offset */0
""",
)
data class Pagination(val limit: Int, val offset: Int)
パーシャルを使用するには、パーシャルをパラメータとして受け取るコマンドを定義し、そのパラメータをSQLテンプレート内で/*> partialName */のように参照します。
@KomapperCommand(
"""
select * from address order by address_id
/*> pagination */
""",
)
class UsePartial(val pagination: Pagination?) : Many<Address>({ selectAsAddress() })
パーシャルのパラメータがnullの場合、パーシャルのSQLはコマンドのSQLには含まれません。
Note
パーシャルは他のパーシャルを参照することはできません。シールドされたサブクラスとしてのパーシャル
パーシャルクラスをシールドされたサブクラスとして表現することができます。 その場合、パーシャルなSQLはポリモーフィックに決定されます。
sealed interface FilterBy {
@KomapperPartial(
"""
where street = /* street */''
""",
)
class Street(val street: String) : FilterBy
@KomapperPartial(
"""
where address_id = /* id */0
""",
)
class Id(val id: Int) : FilterBy
}
@KomapperCommand(
"""
select * from address
/*> filterBy */
""",
)
class UseSealedPartial(val filterBy: FilterBy?) : Many<Address>({ selectAsAddress() })
上記の例では、FilterBy.StreetとFilterBy.Idのどちらのインスタンスが
UseSealedPartialクラスのfilterByパラメータに渡されるかによって、
コマンドのSQLに取り込まれるパーシャルなSQLが変わります。