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

kubo [E-MAIL ADDRESS DELETED]
2009年 10月 21日 (水) 13:01:39 JST


久保(jflute)です。

松原さん、一覧表示の事前件数チェックということですが、
もし、このような機能があったら要件は満たせますでしょう?

XxxPmb pmb = new XxxPmb();
pmb.checkSafetyResult(10000); // 一万件超えちゃダメ
try {
    xxxBhv.outsideSql().manualPaging().selectPage(...);
} catch (DangerousResultSizeException e) {
    int safetySize = e.getSafetyMaxResultSize();
    Integer actualSize = e.getActualResultSize(); // これ必要かな???
    // 一万件超えた時の処理
}
※無論、実現するなら同様の機能をConditionBeanにも


既にConditionBeanでは似たような発想の機能があって、
それをページングの件数取得にも反映させるのは筋が
通ってるかなと思いまして。

cb.checkSafetyResult(100);
xxxBhv.selectList(cb); // 100件超えたら例外

2009/10/20  <[E-MAIL ADDRESS DELETED]>:
> 久保さま
>
> お世話になっております.松原です.
>
>
>>return super.isPaging() && !isCountOnly();
> ⇒が正解ですね.タイプミスです.
>
>>テンプレートの修正が、アップグレード時にロストしないように
>>DBFluteクライアント配下で管理して、sql2entity.bat(sh)などで、
>>DBFluteモジュール内に自動的にコピーすることをお奨めします。
> ⇒その通りですね.こちらの修正したVMファイルは,バッチでコピーするようにします.
>
>>ちなみに松原さんの環境では、この件が
>>(テンプレートを直すまでやるからには)
>>局所的じゃないってところでしょうか?
> ⇒今回は外だしSQL(Select句)がデータ構造から多少多くなっていることと,
> 一覧表示件数の上限があり,事前件数取得が必須となっています.
> また,今回の件をDBFulteでサポートして頂けると私的には有難いですが,
> あまり,スタンダードな使用方法ではないと思いますので,久保さまの判断に
> お任せしたいです.
>
>
> 以上です.大変有難うございました.
>
>>久保(jflute)です。
>>
>>isPaging()のオーバーライド内の判定ですが、
>>return super.isPaging() && isCountOnly();
>>>>return super.isPaging() && !isCountOnly();
>>かと(countOnlyじゃなければtrue)
>>あとテンプレートの修正内容は特に問題なさそうに思えます。
>>テンプレートの修正が、アップグレード時にロストしないように
>>DBFluteクライアント配下で管理して、sql2entity.bat(sh)などで、
>>DBFluteモジュール内に自動的にコピーすることをお奨めします。
>>
>>ちなみに松原さんの環境では、この件が
>>(テンプレートを直すまでやるからには)
>>局所的じゃないってところでしょうか?
>>外だしSQLのページング検索のSQLファイルを使って
>>件数取得だけを単独で実行する業務がたくさんある
>>ということでしょうか?
>>(内容によってはやはりDBFlute側でサポートした方がいいかなと)
>>
>>
>>2009/10/20  <[E-MAIL ADDRESS DELETED]>:
>>> 久保さま
>>>
>>> お世話になっております.松原です.
>>>
>>> 度々すみません.
>>>
>>> 今回の実装を以下のように考えてみなしたが,
>>> 問題ないでしょうか?
>>>
>>> ・DBFluteの自動作成バッチ後に対象クラスの拡張は,再作成のたびに必要となるため,
>>>  DBFluteの自動作成の中に組み込めないか,以下の「BsParameterBean.vm」に
>>>  今回の処理を記述してみました.
>>>
>>>
>>> 「BsParameterBean.vm」に「Customize Attribute」と「Customize Accessor」を追加.
>>>
>>> ***********************************************************
>>> ${database.allClassCopyright}package ${glPackageBaseParameterBean};
>>> #set ($myClassName = "${myBaseParameterBeanClassName}")
>>>
>>> #if ($database.isPmbMetaDataForProcedure($pmbClassName))
>>>
>>> (省略)
>>>    // ===================================================================================
>>>    //                                                                 Customize Attribute
>>>    //                                                                 ====================
>>>    protected boolean countOnly;
>>>
>>>    // ===================================================================================
>>>    //                                                                           Attribute
>>>    //                                                                           =========
>>>
>>> (省略)
>>>
>>>    // ===================================================================================
>>>    //                                                                  Customize Accessor
>>>    //                                                                  ==================
>>> #if ($database.getPmbMetaDataSuperClassDefinition($pmbClassName).indexOf("SimplePagingBean") > 0)
>>>    public boolean isCountOnly() {
>>>        return countOnly;
>>>    }
>>>
>>>    public void setCountOnly(boolean countOnly) {
>>>        this.countOnly = countOnly;
>>>    }
>>>
>>>    @Override
>>>    public boolean isPaging() {
>>>        return super.isPaging() && isCountOnly();
>>>    }
>>> #end
>>>
>>>    // ===================================================================================
>>>    //                                                                            Accessor
>>>    //                                                                            ========
>>>
>>> ***********************************************************
>>>
>>>
>>> 見辛くなりましたが,DBFluteの自動作成バッチに組み込む場合,上記内容で問題ないか
>>> ご教示頂ければ幸いです.
>>>
>>>
>>> 以上です.
>>>
>>>
>>>>久保です。
>>>>
>>>>そうですね、現状では、松原さんの考えの通り、
>>>><B>でisPaging()をオーバーライドするのが良いかと思います。
>>>>
>>>>「ページング検索PmbのisPaging()を(再利用のために)falseにする方法」
>>>>というテーマで、新ドキュメントに反映したいと思います。
>>>>フィードバックありがとうございました。
>>>>
>>>>#
>>>># pmb.disablePaging()みたいなインターフェースを作って
>>>># しまおうかとも思いましたが、状況が局所的であることと、
>>>># よく分かってる人じゃないと理解しづらい機能になるので、
>>>># やはり、「独自プロパティ&isPaging()をオーバーライド」
>>>># という方式を正式なものにしようかと思います。
>>>>#
>>>>
>>>>2009/10/20  <[E-MAIL ADDRESS DELETED]>:
>>>>> 久保さま
>>>>>
>>>>> お世話になっております.松原です.
>>>>>
>>>>> ご返信頂いた内容で全く問題ありません.
>>>>>
>>>>> やはり,現状のDBFluteのParameterBeanでは指定することが
>>>>> できないですね.
>>>>> しかも,拡張の仕方までご教示頂けて,大変有難うございます。
>>>>>
>>>>> 現状,こちらで最適とさせて頂いたのは,<B>のisPaging()をオーバーライドして,
>>>>> 使用する方法がよいと考えております.
>>>>>
>>>>> 説明不足でお手数をお掛けしたこと,申し訳ございませでした.
>>>>>
>>>>> 以上です.貴重な情報を有難うございました.
>>>>>
>>>>>>久保(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 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 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 メーリングリストの案内