[Seasar-user:18716] Re: DBFluteにおけるPagingの件数取得について
[E-MAIL ADDRESS DELETED]
[E-MAIL ADDRESS DELETED]
2009年 10月 21日 (水) 15:35:49 JST
久保さま
お世話になっております.松原です.
ちょっと,今回のこちらの要件が複雑となっており,
(1)対象件数が 100件以内 ⇒ そのまま表示
(2)対象件数が 101件以上 かつ 9,999件以内 ⇒ ワーニング①
(3)対象件数が 10,000件以上 ⇒ ワーニング②
ワーニング①では,取得件数をユーザに通知し,表示を選んだ場合,そのまま取得データを表示
ワーニング②では,取得件数をユーザに通知し,表示を選んだ場合,先頭10,000件のみを表示
以上のようなことから,ご教示頂いた方式でもできなくともないですが,ワーニング①を実装するときに
正常ケースでgetAllRecordCount()の結果から判定するので,ちょっと無駄なデータを取得し
いるようですね.
ご提示して頂いた機能は,非常に使い勝手が良さそうなので,本処理向きではありませんが,
追加して頂けるのであれば,大変有難い機能です.
ワーニング①がない処理の方が一般的と思いますし,本システムでも使用することになるかもしれません.
もし,可能であれば,ご提示機能の検討をお願いしたいです.
因みに
> Integer actualSize = e.getActualResultSize(); // これ必要かな???
は,私にとって,とても必要と思いました.
以上です.
>久保(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 mailing list
>[E-MAIL ADDRESS DELETED]
>https://ml.seasar.org/mailman/listinfo/seasar-user
>
Seasar-user メーリングリストの案内