実行される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. |
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||