実行されるSQL「SELECT * FROM DEPARTMENT ORDER BY DEPTNO」というSQLが次のように書き換えられて実行されます。 SELECT * FROM DEPARTMENT ORDER BY DEPTNO LIMIT 10 OFFSET 55 ROWNUMを使用する方法(Oracleでのみ利用可)OracleのROWNUMを使用する方法です。 j2ee.diconの設定この設定を有効にするには、他のページング用の設定はコメントアウトしてください。 ... <!-- ORACLE ROWNUM句を使ったSQL書き換えによるページング処理用設定 --> <component name="pagingSqlRewriter" class="org.seasar.dao.pager.OracleRownumPagingSqlRewriter"/> <component class="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/> <component class="org.seasar.extension.jdbc.impl.ConfigurableStatementFactory"> <arg> <component class="org.seasar.extension.jdbc.impl.BasicStatementFactory"/> </arg> <property name="fetchSize">100</property> <!-- <property name="maxRows">100</property> --> </component> ... 実行されるSQL「SELECT * FROM DEPARTMENT ORDER BY DEPTNO」というSQLが次のように書き換えられて実行されます(見やすくするために改行を加えています)。 SELECT * FROM (SELECT ROWNUM AS S2DAO_ROWNUMBER, S2DAO_ORIGINAL_DATA.* FROM (SELECT * FROM DEPARTMENT ORDER BY DEPTNO) S2DAO_ORIGINAL_DATA) WHERE S2DAO_ROWNUMBER BETWEEN 56 AND 65 AND ROWNUM <= 10 ORDER BY S2DAO_ROWNUMBER この設定では、全件数を取得するSQLの実行後に、結果セットを取得するSQLを実行します。org.seasar.dao.pager.OracleRownumPagingSqlRewriterのcountSqlCompatibilityプロパティでこのタイミングを変更できますが、通常この設定を変更することはありません。 S2Pagerのユーティリティクラス群S2Pagerにはデータベースアクセスとは離れたレイヤでページングをサポートするいくつかのユーティリティクラスを持ちます。これらのクラスの使用例はサンプルに含まれています。 PagerSupport - セッションへの検索条件の格納をサポート通常、検索条件オブジェクトはHttpSessionのアトリビュートに格納します。 S2Pagerでは検索条件オブジェクトのHttpSessionへの格納などをサポートする ユーティリィ的なクラスとしてorg.seasar.dao.pager.PagerSupportクラスを用意しています。 PagerSupportクラスのコンストラクタで次の項目を指定します。
/** ページャサポートクラス */ private PagerSupport pager = new PagerSupport(10, CategoryPagerCondition.class, "categoryPagerCondition"); セッション中の検索条件DTOの取得開始位置(offset)の更新は、パラメータ名"offset"が取得開始位置を意味する場合次のコードで可能です。 // パラメータoffsetを元にページャのoffset位置を更新 pager.updateOffset(request); また、任意のパラメータ名で更新をしたい場合、次のようなコードになります。 // パラメータ"hoge"を元にページャのoffset位置を更新 pager.updateOffset(request, "hoge"); セッション中の検索条件DTOを取得するには、次のようなコードになります。 // ページャの条件保持オブジェクトをセッションから取得 // 存在しない場合は、PagerSupportのコンストラクタで // 渡されたクラスが新規に作成されます。 CategoryPagerCondition dto = (CategoryPagerCondition) pager.getPagerCondition(request); 以上のPagerSupportの使い方をまとめると、次のようなコードになります。 Actionクラスのインスタンス変数としてPagerSupportを保持していますが、 PagerSupportはスレッドセーフです。複数ユーザで共有して安全に使用することができます。 ただし、最大取得数(limit)をユーザごとに切り替えたい場合は、PagerSupport自体をセッションに格納するなど工夫が必要でしょう。 public BookAction extends Action { /** ページャサポートクラス */ private PagerSupport pager = new PagerSupport(10, CategoryPagerCondition.class, "categoryPagerCondition"); private BookDao bookDao; public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // パラメータoffsetを元にページャのoffset位置を更新 pager.updateOffset(request); // ページャの条件保持オブジェクトをセッションから取得 // 存在しない場合は、PagerSupportのコンストラクタで // 渡されたクラスが新規に作成されます。 CategoryPagerCondition dto = (CategoryPagerCondition) pager.getPagerCondition(request); // 条件保持オブジェクト中の独自の検索条件をセット // この場合、書籍カテゴリを表すcateogry String category = request.getParameter("category"); if (category != null && category.length() != 0) { dto.setCategory(category); } // ページャ対応の検索を実行 List books = bookDao.findByCategoryPagerCondition(dto); request.setAttribute("books", books); // 結果ページにフォワード request.getRequestDispatcher("/result.jsp").forward(request, response); } } PagerViewHelper - ビューの作成を助けるS2Pagerではページリンクを表示するビューの部品は用意していません。 これは、ページリンクの表示形式は、プロジェクトによって異なるためです。 ただ、サンプルは用意しています。 サンプルではJSTL版とJSP2.0のタグファイルによるページリンクの2パターンがあります。 カスタムタグでのサンプルはありません。作成された方はソースの提供お待ちしております;-) また、PagerConditionの情報を元にビューでリンクを生成するためのビューヘルパークラスとして、 org.seasar.dao.pager.PagerViewHelperクラスがあります。 PagerViewHelperクラスを使うとビューで(特にJSTLのELやVelocityで)ページリンクを作成するのが楽になります。PagerViewHelperは以下のメソッドを持っています。 /** * ページャのビューヘルパークラスです。 * @author Toshitaka Agata */ public class PagerViewHelper implements PagerCondition { // コンストラクタ public PagerViewHelper(PagerCondition condition) { ... } public PagerViewHelper(PagerCondition condition, int displayPageMax) { ... } // PagerConditionへの委譲メソッド public int getCount() { ... } public void setCount(int count) { ... } public int getLimit() { ... } public void setLimit(int limit) { ... } public int getOffset() { ... } public void setOffset(int offset) { ... } // ヘルパーメソッド /** * 前へのリンクが表示できるかどうかを判定します。 * @param ture/false */ public boolean isPrev() { ... } /** * 次へのリンクが表示できるかどうかを判定します。 * @param ture/false */ public boolean isNext() { ... } /** * 現在表示中の一覧の最後のoffsetを取得します。 * @param 現在表示中の一覧の最後のoffset */ public int getCurrentLastOffset() { ... } /** * 次へリンクのoffsetを返します。 * @return 次へリンクのoffset */ public int getNextOffset() { ... } /** * 前へリンクのoffsetを返します。 * @return 前へリンクのoffset */ public int getPrevOffset() { ... } /** * 現在ページのインデックスを返します。 * @return 現在ページのインデックス */ public int getPageIndex() { ... } /** * 現在ページのカウント(インデックス+1)を返します。 * @return 現在ページのカウント(インデックス+1) */ public int getPageCount() { ... } /** * 最終ページのインデックスを返します。 * @return 最終ページのインデックス */ public int getLastPageIndex() { ... } /** * ページリンクの表示上限を元に、ページ番号リンクの表示開始位置を返します。 * @return ページ番号リンクの表示開始位置 */ public int getDisplayPageIndexBegin() { ... } /** * ページリンクの表示上限を元に、ページ番号リンクの表示終了位置を返します。 * @return ページ番号リンクの表示終了位置 */ public int getDisplayPageIndexEnd() { ... } 以下はサンプルにあるJSTLによるページリンクの実装例です。 <!--ページャー(件数表示あり)--> <c:import url="tags/pager.jsp"> <c:param name="condition" value="categoryPagerCondition"/>・・・検索条件DTOのセッション中の属性名を指定 </c:import>ページャリンクの部品:pager.jsp <%@ page contentType="text/html; charset=Windows-31J" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% // パラメータの取得 String conditionName = request.getParameter("condition"); String counter = request.getParameter("counter"); String href = request.getParameter("href"); // PagerViewHelperの作成 org.seasar.dao.pager.PagerCondition condition = (org.seasar.dao.pager.PagerCondition)pageContext.findAttribute(conditionName); org.seasar.dao.pager.PagerViewHelper helperCondition = new org.seasar.dao.pager.PagerViewHelper(condition); // 属性をセット pageContext.setAttribute("counter", counter); pageContext.setAttribute("href", href); pageContext.setAttribute("helperCondition", helperCondition); %> <%-- メイン --%> <table border="0" cellpadding="0" cellspacing="0"> <tr> <c:if test="${counter != 'false'}"> <td width="200" align="left" valign="center"> 該当件数:<c:out value="${helperCondition.count}"/>件 (<c:out value="${helperCondition.offset + 1}"/> -<c:out value="${helperCondition.currentLastOffset + 1}"/>) </td> </c:if> <td align="right" valign="center"> <c:if test="${helperCondition.prev}"> <a href="<c:out value="${href}"/>?offset= <c:out value="${helperCondition.prevOffset}"/>">< 前の <c:out value="${helperCondition.limit}"/>件</a> </c:if> <c:forEach begin="0" end="${helperCondition.lastPageIndex}" step="1" varStatus="status"> <c:if test="${status.index != helperCondition.pageIndex}"> <a href="<c:out value="${href}"/>?offset= <c:out value="${status.index * helperCondition.limit}"/>"> <c:out value="${status.count}"/></a> </c:if> <c:if test="${status.index == helperCondition.pageIndex}"> [<c:out value="${status.count}"/>] </c:if> </c:forEach> <c:if test="${helperCondition.next}"> <a href="<c:out value="${href}"/>?offset= <c:out value="${helperCondition.nextOffset}"/>">次の <c:out value="${helperCondition.limit}"/>件 ></a></td> </c:if> <c:if test="${!helperCondition.next}"> </c:if> </tr> </table> PagerUtil - S2Daoを使わないList,Colllecitonに対するページングS2Daoを使わないList,Colllecitonに対してページングを行いたいときはPagerUtil#filterを使用します。 List list = getItems(); // フィルタリング前のリスト DefaultPagerCondition condition = new DefaultPagerCondition(); condition.setLimit(10); condition.setOffset(10); List result = PagerUtil.filter(list, condition); System.out.println(result.size()); // 10 System.out.println(condition.getCount()); // 35 サンプルS2PagerのサンプルはJSP2.0で動作します。以下の手順でTomcat5.0.xなどJSP2.0をサポートするServletコンテナ上で動作させる必要があります。
Tomcatプラグインを導入している環境であれば、EclipseのTomcatPlugin上でそのまま動作させることもできます。
|
|
|
| © Copyright The Seasar Foundation and the others 2004-2011, all rights reserved. |
| |||||||||||||||||||||||||||||||||||||||||||||||||||