[Seasar-user:18693] Re: DBFluteにおけるPagingの件数取得について

kubo [E-MAIL ADDRESS DELETED]
2009年 10月 20日 (火) 20:01:01 JST


久保(jflute)です。

状況わかりました。ありがとうございます。

通常の外だしSQLのページング検索用に作成されたSQLを再利用して、
件数取得だけに絞って実行したいという感じでしょうか。
(別のSQLにするとWhere句が冗長してしまうので)
そして、ページング実データが必要になるケースも
別のプログラムで存在するのですよね???

これが前提として:

(1) ページングで取得する件数を1件に設定して
   「outsideSql().autoPaging().selectPage」を呼出す
だと、不要なページング実データが一件とはいえ取得してしまいます。

(2) Select Count(*) のみの外だしSQLを別途作成する
だと、Where句が冗長してしまいます。

<A>
pmb.xsetPaging(false)で確かにisPaging()がfalseになりますが、
「x」で始まるメソッドは極力アプリケーションで直接利用して
欲しくないメソッドではあります。互換性の保証はなく、
あるときにメソッド名が変わってしまう可能性もあります。

なのでそれよりは、以下のように明示的なクラスを作成して、
利用する方がプログラムの可読性としても良いかなと思います。
(無名インナークラスでやるとIllegalAccessになってしまいました...)

public static class CountOnlyXxxPmb extends XxxPmb {
    public boolean isPaging() {
        return false;
    }
}

<B>
もう一つは、XxxPmbに新たに[boolean countOnly]というような
プロパティを追加して、isPaging()と一緒に判定させてあげるように
するのも良いかと思います。

パラメータコメントにてisPaging()と必ず一緒に判定:
/*IF pmb.isPaging() && !pmb.isCountOnly()*/
/*END*/

もしくは

ExParameterBeanでisPaging()をオーバーライドして一緒に判定:
public class XxxPmb extends BsXxxPmb {
    public boolean isPaging() {
        return super.isPaging() && !isCountOnly();
    }
}

後者の方が単体テストでテストもしやすくタイプセーフですね。
そして、アプリケーションでの呼び出しにて以下のように:
XxxPmb pmb = new XxxPmb();
pmb.setCountOnly(true);
int count = bhv.outsideSql().entityHandling().selectEntity(...);


#
# ポイントなのは、DBFluteも単に2WaySQLの仕組みの
# 範疇で便利な機能を作っているだけってところですね。
# なので、2WaySQLの仕組みを利用することでアレンジ可能です。
#

2009/10/20  <[E-MAIL ADDRESS DELETED]>:
> 久保さま
>
>
> お世話になっております.松原です.
> 迅速なご返信,大変ありがとうございます.
>
> 言葉足らずで申し訳ございません.
> 以下,本文中に以下インサートで回答させて頂きます.
>
>>久保(jflute)です。
>>
>>松原さん、こんばんは
>>
>>まずは、前提としてこちらのページをご覧下さい。
>>http://dbflute.sandbox.seasar.org/contents/behavior/paging.html
>>
>>確認させて下さい。
>>
>><1>
>>「Paging機能を使用して件数を取得したい」というのは、
>>「ページングなし件数取得」のことでよろしいでしょうか?
> ⇒ その通りです.
>
>>
>><2>
>>「Paging機能を使用して件数を取得したい」とのことですが、
>>ページング実データ(例えば、20件目から40件目のレコード)は
>>不要なのでしょうか?
> ⇒ 不要です.言葉足らずで申し訳ございません.
>
>>
>>
>>通常の外だしSQLでのページング検索は、
>>http://dbflute.sandbox.seasar.org/contents/outside-sql/paging.html
>>このような感じになります。
>>
>>PagingResultBean<UnpaidSummaryMember> page
>>    = memberBhv.outsideSql().autoPaging().selectPage(path, pmb, entityType);
>>
>>int allRecordCount = page.getAllRecordCount(); // ページングなし件数
>>for (UnpaidSummaryMember member : page) { // ページング実データ
>>}
>>
> ⇒ この場合,結果として件数だけでなくSELECT句の全カラムも取得していると認識していましたが,
> 以下の「pmb.isPaging()」をfalseとなるように実行すれば、件数のみが取得できると勝手
> に憶測した次第でした。
>
> では、SQLの実行速度及びデータ転送量を最小限に抑えて,外だしSQLの件数取得を行う場合,
> (1) ページングで取得する件数を1件に設定して「outsideSql().autoPaging().selectPage」
> を呼出す
> (2) Select Count(*) のみの外だしSQLを別途作成する
> の2通りで実装するのが望ましいということでしょうか?
>
> また,「ParameterBean#xsetPaging(false);」で一応,件数取得ができているに見えましたが,
> 使用してはいけないと認識してよろしいでしょうか?
>
>
>  /*IF pmb.isPaging()*/
>  select member.MEMBER_ID
>     , member.MEMBER_NAME
>     , ...
>  -- ELSE select count(*)
>  /*END*/
>
>
> 以上です.宜しくお願い致します.
>
>
>
>>2009/10/20  <[E-MAIL ADDRESS DELETED]>:
>>>
>>> お世話になっております.松原です.
>>>
>>>
>>> 掲題の件,実装方法がサイトから見出すことができず,
>>> 初歩的な質問とは,思いますが,Paging機能を使用して,
>>> 件数を取得したい場合,以下の使用方法で問題ないか
>>> ご教示頂けないでしょうか?
>>>
>>>
>>> ===============================================
>>> <サイトの例>
>>> /*IF pmb.isPaging()*/
>>> select member.MEMBER_ID
>>>     , member.MEMBER_NAME
>>>     , ...
>>> -- ELSE select count(*)
>>> /*END*/
>>>
>>>
>>> <使用時の解釈>
>>> // Parameterの設定
>>> final prm = new XxxPmb();
>>> prm.setName("'テスト'");
>>>
>>> prm.xsetPaging(false);      // ← (1)このメソッドでPagingをOFF?
>>>
>>> int cnt = XxxBhv.outsideSql.entityHandling.selectEntity(XxxBhv.PATH_select, prm, Integer.class);
>>>
>>> System.out.println(cnts);   // ← (2)この結果に件数が入っている?
>>>
>>> ===============================================
>>>
>>> (1)と(2)の使い方が正しいか,ご確認の程,宜しくお願いします.
>>>
>>>
>>> 以上.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> Seasar-user mailing list
>>> [E-MAIL ADDRESS DELETED]
>>> https://ml.seasar.org/mailman/listinfo/seasar-user
>>>
>>_______________________________________________
>>Seasar-user mailing list
>>[E-MAIL ADDRESS DELETED]
>>https://ml.seasar.org/mailman/listinfo/seasar-user
>>
>
> _______________________________________________
> Seasar-user mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-user
>
>


Seasar-user メーリングリストの案内