UPDATEクエリ

更新のためのクエリ

概要

UPDATEクエリはQueryDslupdateとそれに続く関数を呼び出して構築します。

クエリ実行時にキーが重複した場合、org.komapper.core.UniqueConstraintExceptionがスローされます。

single

エンティティ1件を更新するにはsingleを呼び出します。

val address: Address = ..
val query: Query<Address> = QueryDsl.update(a).single(address)
/*
update ADDRESS set STREET = ?, VERSION = ? + 1 where ADDRESS_ID = ? and VERSION = ?
*/

このクエリを実行した場合の戻り値は更新されたデータを表す新しいエンティティです。

下記のマッピング定義に応じて、発行されるSQLにも新しいエンティティにも適切な値が反映されます。

  • @KomapperId
  • @KomapperVersion
  • @KomapperUpdatedAt

クエリ実行時に楽観的排他制御が失敗した場合、org.komapper.core.OptimisticLockExceptionがスローされます。

クエリ実行時にエンティティが見つからなかった場合、org.komapper.core.EntityNotFoundExceptionがスローされます。

batch

バッチでエンティティ複数件を更新するにはbatchを呼び出します。

val address1: Address = ..
val address2: Address = ..
val address3: Address = ..
val query: Query<List<Address>> = QueryDsl.update(a).batch(address1, address2, address3)
/*
update ADDRESS set STREET = ?, VERSION = ? + 1 where ADDRESS_ID = ? and VERSION = ?
update ADDRESS set STREET = ?, VERSION = ? + 1 where ADDRESS_ID = ? and VERSION = ?
update ADDRESS set STREET = ?, VERSION = ? + 1 where ADDRESS_ID = ? and VERSION = ?
*/

このクエリを実行した場合の戻り値は更新されたデータを表す新しいエンティティのリストです。

下記のマッピング定義に応じて、発行されるSQLにも新しいエンティティにも適切な値が反映されます。

  • @KomapperVersion
  • @KomapperUpdatedAt

クエリ実行時に楽観的排他制御が失敗した場合、org.komapper.core.OptimisticLockExceptionがスローされます。

クエリ実行時にエンティティが見つからなかった場合、org.komapper.core.EntityNotFoundExceptionがスローされます。

include

singlebatch の実行で特定のプロパティのみを更新対象に含めるには事前にinclude関数を呼び出します。

val department: Department = ..
val query: Query<Department> = QueryDsl.update(d).include(d.departmentName).single(department)
/*
update DEPARTMENT set DEPARTMENT_NAME = ?, VERSION = ? + 1 where DEPARTMENT_ID = ? and VERSION = ?
*/

include関数の呼び出しに関係なく、 以下のアノテーションで注釈されたプロパティは常に更新対象に含まれます。

  • @KomapperVersion
  • @KomapperUpdatedAt

exclude

singlebatch の実行で特定のプロパティを更新対象から除外するには事前にexclude関数を呼び出します。

val department: Department = ..
val query: Query<Department> = QueryDsl.update(d).exclude(d.departmentName).single(department)
/*
update DEPARTMENT set DEPARTMENT_NO = ?, LOCATION = ?, VERSION = ? + 1 where DEPARTMENT_ID = ? and VERSION = ?
*/

exclude関数の呼び出しに関係なく、 以下のアノテーションで注釈されたプロパティは常に更新対象に含まれます。

  • @KomapperVersion
  • @KomapperUpdatedAt

set

任意のプロパティに更新データをセットするにはset関数にラムダ式を渡します。

ラムダ式の中ではeq関数を使って値を設定できます。

val query: Query<Long> = QueryDsl.update(a).set {
  a.street eq "STREET 16"
}.where {
  a.addressId eq 1
}
/*
update ADDRESS as t0_ set STREET = ? where t0_.ADDRESS_ID = ?
*/

eqIfNotNullを使って値がnullでない場合にのみ値を設定することもできます。

val query: Query<Long> = QueryDsl.update(e).set {
  e.managerId eqIfNotNull managerId
  e.employeeName eq "test"
}.where {
  e.employeeId eq 1
}

これらのクエリを実行した場合の戻り値は更新された件数です。

以下のマッピング定義を持つプロパティについて明示的にeqを呼び出さない場合、発行されるSQLに自動で値が設定されます。 明示的にeqを呼び出した場合は明示した値が優先されます。

  • @KomapperVersion
  • @KomapperUpdatedAt

where

任意の条件にマッチする行を更新するにはwhereを呼び出します。

val query: Query<Long> = QueryDsl.update(a).set {
  a.street eq "STREET 16"
}.where {
  a.addressId eq 1
}
/*
update ADDRESS as t0_ set STREET = ? where t0_.ADDRESS_ID = ?
*/

デフォルトではWHERE句の指定は必須でありWHERE句が指定されない場合は例外が発生します。 意図的に全件更新を認める場合はoptionsを呼び出してallowMissingWhereClausetrueを設定します。

val query: Query<Long> = QueryDsl.update(e).set {
    e.employeeName eq "ABC"
}.options { 
    it.copy(allowMissingWhereClause = true)
}

このクエリを実行した場合の戻り値は更新された件数です。

returning

以下の関数の後続でreturning関数を呼び出すことで、更新された値を取得できます。

  • single
  • set

single関数の後続でreturning関数を呼び出す例です。

val address: Address = ..
val query: Query<Address?> = QueryDsl.update(a).single(address).returning()
/*
update ADDRESS set STREET = ?, VERSION = ? + 1 where ADDRESS_ID = ? and VERSION = ? returning ADDRESS_ID, STREET, VERSION
*/

returning関数にプロパティを指定することで取得対象のカラムを限定できます。

val query: Query<Int?> = QueryDsl.update(a).single(address).returning(a.addressId)
/*
update ADDRESS set STREET = ?, VERSION = ? + 1 where ADDRESS_ID = ? and VERSION = ? returning ADDRESS_ID
*/
val query: Query<Pair<Int?, String?>?> = QueryDsl.update(a).single(address).returning(a.addressId, a.street)
/*
update ADDRESS set STREET = ?, VERSION = ? + 1 where ADDRESS_ID = ? and VERSION = ? returning ADDRESS_ID, STREET
*/
val query: Query<Triple<Int?, String?, Int?>?> = QueryDsl.update(a).single(address).returning(a.addressId, a.street, a.version)
/*
update ADDRESS set STREET = ?, VERSION = ? + 1 where ADDRESS_ID = ? and VERSION = ? returning ADDRESS_ID, STREET, VERSION
*/

options

クエリの挙動をカスタマイズするにはoptionsを呼び出します。 ラムダ式のパラメータはデフォルトのオプションを表します。 変更したいプロパティを指定してcopyメソッドを呼び出してください。

val address: Address = ..
val query: Query<Address> = QueryDsl.update(a).single(address).options {
    it.copy(
      queryTimeoutSeconds = 5
    )
}

指定可能なオプションには以下のものがあります。

allowMissingWhereClause
空のWHERE句を認めるかどうかです。デフォルトはfalseです。
escapeSequence
LIKE句に指定されるエスケープシーケンスです。デフォルトはnullDialectの値を使うことを示します。
batchSize
バッチサイズです。デフォルトはnullです。
disableOptimisticLock
楽観的ロックを無効化するかどうかです。デフォルトはfalseです。この値がtrueのときWHERE句にバージョン番号が含まれません。
queryTimeoutSeconds
クエリタイムアウトの秒数です。デフォルトはnullでドライバの値を使うことを示します。
suppressLogging
SQLのログ出力を抑制するかどうかです。デフォルトはfalseです。
suppressOptimisticLockException
楽観的ロックの取得に失敗した場合にOptimisticLockExceptionのスローを抑制するかどうかです。デフォルトはfalseです。
suppressEntityNotFoundException
エンティティが見つからない場合にEntityNotFoundExceptionのスローを抑制するかどうかです。デフォルトはfalseです。

executionOptions の同名プロパティよりもこちらに明示的に設定した値が優先的に利用されます。