更新
DAO メソッドに @Update
を付けて、更新操作を実行します。
@Dao
public interface EmployeeDao {
@Update
int update(Employee employee);
@Update
Result<ImmutableEmployee> update(ImmutableEmployee employee);
}
デフォルトでは、UPDATE ステートメントが自動生成されます。 @Update
アノテーション内の sqlFile
プロパティに true
を指定することで、任意の SQL ファイルをマッピングできます。
エンティティクラスパラメータにエンティティリスナーが指定されている場合、更新を実行する前にエンティティリスナーの preUpdate
メソッドが呼び出されます。同様に、更新を実行した後、エンティティリスナーの postUpdate
メソッドが呼び出されます。
戻り値
returning プロパティを使用する場合
returning を参照してください。
returning プロパティを使用しない場合
パラメータが不変エンティティクラスの場合、戻り値はそのエンティティクラスを要素とする org.seasar.doma.jdbc.Result
でなければなりません。
上記の条件が満たされない場合、戻り値は更新された行数を表す int
である必要があります。
自動生成されたSQLによる更新
パラメータの型はエンティティクラスである必要があります。指定できるパラメータは1つだけです。パラメータはnullであってはなりません。
@Update
int update(Employee employee);
@Update
Result<ImmutableEmployee> update(ImmutableEmployee employee);
自動生成された SQL におけるバージョン番号と楽観的排他制御
以下の条件を満たした場合、楽観的排他制御が実行されます。
パラメータのエンティティクラスが @Version アノテーションが付けられたプロパティを持つ
@Update アノテーション内のignoreVersion要素がfalseである
楽観的同時実行制御が有効になっている場合、バージョン番号は識別子とともに更新条件に含まれ、1ずつ増加されます。更新数が0の場合、楽観的同時実行制御の失敗を示すために``OptimisticLockException`` がスローされます。更新数が0でない場合、OptimisticLockException
はスローされず、エンティティ内のバージョンプロパティは1増加します。
ignoreVersion
@Update
アノテーション内の ignoreVersion
プロパティが true
の場合、バージョン番号は更新条件に含まれず、UPDATE ステートメント内の SET 句に含まれます。バージョン番号はアプリケーションで設定した値により更新されます。更新件数が 0 であっても OptimisticLockException
はスローされません。
@Update(ignoreVersion = true)
int update(Employee employee);
suppressOptimisticLockException
@Update
アノテーションの suppressOptimisticLockException
プロパティが true
の場合、@Version
アノテーションが付けられたプロパティが存在すればバージョン番号は更新条件に含まれ増分もされますが、更新件数が0でも OptimisticLockException
はスローされません。ただし、エンティティのバージョンプロパティの値は1増分されます。
@Update(suppressOptimisticLockException = true)
int update(Employee employee);
更新対象プロパティの制御
updatable
エンティティクラスのプロパティで @Column
に注釈が付けられたもののうち、updatable
プロパティが false
に設定されているものは更新対象から除外されます。
exclude
@Update
アノテーションの exclude
プロパティに指定されたプロパティは更新対象から除外されます。たとえ @Column
アノテーションの updatable
プロパティが true
に設定されていても、exclude
プロパティにリストされているプロパティは更新されません。
@Update(exclude = {"name", "salary"})
int update(Employee employee);
include
@Update
アノテーションの include
プロパティに指定されたプロパティのみが更新されます。@Update
の include
プロパティと exclude
プロパティの両方に同じプロパティがある場合、そのプロパティは更新されません。たとえ include
プロパティにリストされていても、その @Column
アノテーションの updatable
プロパティが false
に設定されている場合は更新されません。
@Update(include = {"name", "salary"})
int update(Employee employee);
excludeNull
@Update
アノテーションの``excludeNull`` プロパティが true
に設定されている場合、null
の値を持つプロパティは更新されません。これは他の設定よりも優先されます - プロパティの``@Column`` の``updatable`` 属性が true
に設定されている場合や``@Update`` アノテーションの``include``プロパティにそのプロパティがリストされている場合でも、その値が``null`` の場合は更新されません。
@Update(excludeNull = true)
int update(Employee employee);
includeUnchanged
このプロパティは、更新されるエンティティクラスに``@OriginalStates``で注釈が付けられたプロパティが含まれている場合にのみ有効です。
この要素が``true``に設定されている場合、エンティティ内のすべてのプロパティが更新されます。つまり、すべてのプロパティに対応する列がUPDATEステートメントのSET句に含まれます。
この要素が false
の場合、エンティティが取得されてから実際に変更されたプロパティのみが更新対象になります。つまり、変更されたプロパティに対応するカラムのみがUPDATE文のSET句に含まれます。
@Update(includeUnchanged = true)
int update(Employee employee);
returning
returning
プロパティで @Returning
を指定することで、SQL の UPDATE .. RETURNING
句に相当するコードを生成できます。
@Dao
public interface EmployeeDao {
@Update(returning = @Returning)
Employee update(Employee employee);
@Update(returning = @Returning(include = { "employeeId", "version" }))
Employee updateReturningIdAndVersion(Employee employee);
@Update(returning = @Returning(exclude = { "password" }))
Employee updateReturningExceptPassword(Employee employee);
@Update(returning = @Returning, suppressOptimisticLockException = true)
Optional<Employee> updateOrIgnore(Employee employee);
}
@Returning
の include
要素を使用して、RETURNING 句によって返されるエンティティのプロパティ(データベース列に対応)を指定できます。また、exclude
要素を使用して、結果から除外すべきプロパティを指定することもできます。同じプロパティが include
と exclude
の両方に含まれている場合、それは返されません。
戻り値の型は、エンティティクラスまたはエンティティクラスを要素として含む Optional
のいずれかでなければなりません。
注釈
この機能は、H2 Database、PostgreSQL、SQL Server、およびSQLiteのダイアレクトのみがサポートしています。
SQLファイルによる更新
SQLファイルによる更新を行うには、 @Update
の sqlFile
プロパティに true
を設定し、メソッドに対応するSQLファイルを用意します。
注釈
SQLファイルによる更新では 更新カラムリスト生成ディレクティブ を使用する場合と使用しない場合でルールが異なります。
populate ディレクティブを使用する場合
最初のパラメータの型はエンティティクラスである必要があります。指定できるパラメータの数に制限はありません。パラメータの型が基本型またはドメインクラスの場合、パラメータに null
を設定できます。型がそれ以外の場合、パラメータは null
であってはなりません。
@Update(sqlFile = true)
int update(Employee employee, BigDecimal salary);
@Update(sqlFile = true)
Result<ImmutableEmployee> update(ImmutableEmployee employee, BigDecimal salary);
たとえば、上記のメソッドに対応するSQLは次のように記述します。
update employee set /*%populate*/ id = id where salary > /* salary */0
対象プロパティの更新制御に関するルールは 自動生成されたSQLによる更新 と同様です。
populateディレクティブを使用しない場合
任意の型をパラメータとして使用できます。指定できるパラメータの数に制限はありません。パラメータの型が基本型またはドメインクラスの場合、パラメータに null
を設定できます。型がそれ以外の場合、パラメータは null
であってはなりません。
@Update(sqlFile = true)
int update(Employee employee);
@Update(sqlFile = true)
Result<ImmutableEmployee> update(ImmutableEmployee employee);
たとえば、上記のメソッドに対応するSQLは次のように記述します。
update employee set name = /* employee.name */'hoge', salary = /* employee.salary */100
where id = /* employee.id */0
@Update
アノテーション内の exclude
プロパティおよび include
プロパティ、excludeNull
プロパティ、includeUnchanged
プロパティは、SQL ファイルによる更新時に参照されません。
SQLファイルにおけるバージョン番号と楽観的排他制御
以下の条件を満たした場合、楽観的排他制御が実行されます。
パラメータにエンティティクラスが含まれる
パラメータの <em>左端</em> のエンティティクラスは、@Version アノテーションが付けられたプロパティを持つ。
@Update アノテーション内のignoreVersion要素がfalseである
ただし、楽観的排他制御のSQLの記述はアプリケーション開発者の責任となります。たとえば、以下の SQL のように、WHERE 句でバージョン番号を指定し、SET 句でバージョン番号を 1 ずつインクリメントする必要があります。
update EMPLOYEE set DELETE_FLAG = 1, VERSION = /* employee.version */1 + 1
where ID = /* employee.id */1 and VERSION = /* employee.version */1
このSQL文の更新数が0の場合、楽観的排他制御の失敗を示す OptimisticLockException
がスローされます。更新数が0でない場合、OptimisticLockException
はスローされず、エンティティ内のバージョンプロパティは1増加されます。
ignoreVersion
@Update
の ignoreVersion
要素が true
の場合、更新件数が0件であっても、 OptimisticLockException
はスローされません。 また、エンティティのバージョンプロパティの値は変更されません。
@Update(sqlFile = true, ignoreVersion = true)
int update(Employee employee);
suppressOptimisticLockException
@Update
の suppressOptimisticLockException
要素が true
の場合、更新件数が0件であっても、 OptimisticLockException
はスローされません。 ただし、エンティティのバージョンプロパティの値は1増分されます。
@Update(sqlFile = true, suppressOptimisticLockException = true)
int update(Employee employee);
一意制約違反
SQLファイルの使用にかかわらず、ユニーク制約違反が発生すると UniqueConstraintException
がスローされます。
クエリタイムアウト
@Update
アノテーション内の queryTimeout
プロパティにクエリタイムアウトの秒数を指定できます
@Update(queryTimeout = 10)
int update(Employee employee);
この仕様は、SQLファイルが使用されるかどうかにかかわらず適用されます。queryTimeout
プロパティが設定されていない場合、設定 に指定されているクエリタイムアウトが適用されます。
SQLログの出力形式
@Update
の sqlLog
プロパティを使用して SQL ログ出力形式を指定できます。
@Update(sqlLog = SqlLogType.RAW)
int update(Employee employee);
SqlLogType.RAW
は、バインドパラメータでSQLをログに記録することを示します。