queryUpdate(entity, cb)

概要

基本概念

ConditionBean の絞り込み条件に一致するレコード全てを更新します。

例えば、"未払い購入のある正式会員を仮会員に更新"、"退会会員の生年月日を null に更新" というような更新ができます。Entity に加えて、ConditionBean を指定します。

共通カラムの自動設定はされます。排他制御カラムの更新はありますが、排他制御処理はありません。

条件なしでの更新(NonQueryUpdate)は、デフォルトでは許可されません(@since 0.9.7.8)

会話上では、くえりあっぷでーと と表現します。ConditionBean のあっぷでーと とも言えます。

実装方法

実装の流れ ※1.1.x (Java8版)

Behaviorの queryUpdate() を呼び出し、Entity と ConditionBean を指定します。

e.g. queryUpdate()の実装手順 (Eclipseでコード補完) {MEMBER} @Java
memberBhv.quU // .quU と打って enter
--

// メソッドが補完されて、第一引数の "member" が選択状態に
// tabで移動して、第二引数の "cbLambda" を選択状態にして...
memberBhv.queryUpdate(member, cbLambda)
--

// cbLambdaの部分で、_ll (補完テンプレートが有効なら)
memberBhv.queryUpdate(member, _ll)
--

// Lambda引数名はcbにして...セミコロン ";" を忘れずに
memberBhv.queryUpdate(member, cb -> {
    cb.query().set... // tabでカーソル移動してcbで検索条件
});
--

Entity には PK の値も不要です。更新値だけを設定します。

e.g. 未払い購入のある正式会員を仮会員に更新 @Java
Member member = new Member();
member.setMemberStatusCode_Provisional();
member.setFormalizedDatetime(null);
memberBhv.queryUpdate(member, cb -> {
    cb.query().setMemberStatusCode_Equal_Formalized();
    cb.query().existsPurchase(puchaseCB -> {
        puchaseCB.query().setPaymentCompeleteFlg_Equal_False();
    });
});
e.g. 未払い購入のある正式会員を仮会員に更新 @DisplaySql
update MEMBER
   set MEMBER_STATUS_CODE = 'PRV'
     , FORMALIZED_DATETIME = null
     , UPDATE_DATETIME = '2010-11-16 15:54:48.624'
     , UPDATE_USER = 'testUser'
     , UPDATE_PROCESS = 'WxBhvQueryUpdateTest[main]'
     , VERSION_NO = VERSION_NO + 1
 where MEMBER_ID in (
select dfloc.MEMBER_ID 
  from MEMBER dfloc 
 where dfloc.MEMBER_STATUS_CODE = 'FML'
   and exists (select sub1loc.MEMBER_ID
                 from PURCHASE sub1loc 
                where sub1loc.MEMBER_ID = dfloc.MEMBER_ID
                  and sub1loc.PAYMENT_COMPLETE_FLG = 0
       )
)

絞り込み条件は、(基本的には) InScope を使ったサブクエリ方式です。

実装の流れ ※1.0.x (Java6版)

e.g. queryUpdate()の実装手順 (Eclipseでコード補完) {MEMBER} @Java
memberBhv.quU // .quU と打って enter
--
memberBhv.queryUpdate(member, cb);

// .qu と打つと queryUpdate() や queryDelete() など
// クエリ更新系のメソッドだけが補完候補に列挙される

主キー値の更新

PK も更新対象カラムの一つです。あまりお奨めされませんが、PKのプロパティに値を設定すれば更新できます。

メソッド仕様

引数

該当のBehaviorに対応するテーブルの Entity と ConditionBean (1.1.xよりコールバック) になります。

nullを指定した場合は例外発生します。

戻り値

更新したレコードの件数が戻ります。更新対象が存在しなかった場合は 0 が戻ります。

例外

一意制約違反があった場合
org.seasar.dbflute.exception.EntityAlreadyExistsException
DBFluteで正式サポートしていない DBMS では、別の例外(SQLFailureException)の可能性があります。
条件なし更新(全件更新)の場合
org.seasar.dbflute.exception.NonQueryUpdateNotAllowedException

DBMSによっては制限も

DBMSによっては利用できる機能に制限があります。例えば、MySQLは、update 文の where 句のサブクエリにて更新対象のテーブルを参照できない、という制約があるため、サブクエリ方式ではなく、where 句に直接条件を展開しています。すると、Query(Relation) や ExistsReferrer などの関連テーブルを利用した絞り込み条件が利用できなくなります。

複合主キーの場合は制限

複合主キーの場合は制限は、サブクエリ方式が利用できないため、MySQLと同じ制限になります。

共通カラムの自動設定

update(entity) と同じ仕様です。

排他制御処理なし

排他制御カラムは更新(バージョン番号のインクリメントなど)されますが、排他制御処理はありません。

カスケードはしません

update(entity) と同じ仕様です。

Entity更新のスコープ

update(entity) と同じ仕様です。

条件なしでの更新(全件更新)

条件なしでの更新(NonQueryUpdate)は、デフォルトでは許可されません(@since 0.9.7.8)。 (万が一の)不意の全件更新を防ぐためです。どうしても全件更新をしたい場合は、varyingQueryUpdate() を利用し、UpdateOption で許可するオプションを指定することで実現できます。

varyingQueryUpdate(entity, cb, option)