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

[E-MAIL ADDRESS DELETED] [E-MAIL ADDRESS DELETED]
2009年 10月 20日 (火) 22:56:50 JST


久保さま

 お世話になっております.松原です.


>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 メーリングリストの案内