???? 前面一篇直接使用了 Myfaces 中的兩個 Component 完成了一個簡單的分頁,這里將會介紹一種 On-demand loading 的方法來進行分頁,僅僅在需要數(shù)據(jù)的時候加載。
???? 先來說一些題外話,為了實現(xiàn)這種方式的分頁,公司里大約 5-6 個人做了半個多月的工作,擴展了 dataTable ,修改了 dataScrollor ,以及各種其他的方法,但是都不是很優(yōu)雅。在上個月底的時候,在 Myfaces 的 Mail List 中也針對這個問題展開了一系列的討論,最后有人總結(jié)了討論中提出的比較好的方法,提出了以下的分頁方法,也是目前實現(xiàn)的最為優(yōu)雅的方法,也就是不對 dataTable 和 dataScrollor 做任何修改,僅僅通過擴展 DataModel 來實現(xiàn)分頁。
???? DataModel 是一個抽象類,用于封裝各種類型的數(shù)據(jù)源和數(shù)據(jù)對象的訪問, JSF 中 dataTable 中綁定的數(shù)據(jù)實際上被包裝成了一個 DataModel ,以消除各種不同數(shù)據(jù)源和數(shù)據(jù)類型的復(fù)雜性,在前面一篇中我們訪問數(shù)據(jù)庫并拿到了一個 List ,交給 dataTable ,這時候, JSF 會將這個 List 包裝成 ListDataModel , dataTable 訪問數(shù)據(jù)都是通過這個 DataModel 進行的,而不是直接使用 List 。
????
接下來我們要將需要的頁的數(shù)據(jù)封裝到一個
DataPage
中去,這個類表示了我們需要的一頁的數(shù)據(jù),里面包含有三個元素:
datasetSize
,
startRow
,和一個用于表示具體數(shù)據(jù)的
List
。
datasetSize
表示了這個記錄集的總條數(shù),查詢數(shù)據(jù)的時候,使用同樣的條件取
count
即可,
startRow
表示該頁的起始行在數(shù)據(jù)庫中所有記錄集中的位置。
?*?A?simple?class?that?represents?a?"page"?of?data?out?of?a?longer?set,?ie?a
?*?list?of?objects?together?with?info?to?indicate?the?starting?row?and?the?full
?*?size?of?the?dataset.?EJBs?can?return?instances?of?this?type?when?returning
?*?subsets?of?available?data.
? */
public ? class ?DataPage
{
???? private ? int ?datasetSize;
???? private ? int ?startRow;
???? private ?List?data;
???? /**
?????*?Create?an?object?representing?a?sublist?of?a?dataset.
?????*?
?????*? @param ?datasetSize
?????*????????????is?the?total?number?of?matching?rows?available.
?????*?
?????*? @param ?startRow
?????*????????????is?the?index?within?the?complete?dataset?of?the?first?element
?????*????????????in?the?data?list.
?????*?
?????*? @param ?data
?????*????????????is?a?list?of?consecutive?objects?from?the?dataset.
????? */
???? public ?DataPage( int ?datasetSize,? int ?startRow,?List?data)
???? {
???????? this .datasetSize? = ?datasetSize;
???????? this .startRow? = ?startRow;
???????? this .data? = ?data;
????}
???? /**
?????*?Return?the?number?of?items?in?the?full?dataset.
????? */
???? public ? int ?getDatasetSize()
???? {
???????? return ?datasetSize;
????}
???? /**
?????*?Return?the?offset?within?the?full?dataset?of?the?first?element?in?the
?????*?list?held?by?this?object.
????? */
???? public ? int ?getStartRow()
???? {
???????? return ?startRow;
????}
???? /**
?????*?Return?the?list?of?objects?held?by?this?object,?which?is?a?continuous
?????*?subset?of?the?full?dataset.
????? */
???? public ?List?getData()
???? {
???????? return ?data;
????}
}
?
???? 接下來,我們要對 DataModel 進行封裝,達到我們分頁的要求。該 DataModel 僅僅持有了一頁的數(shù)據(jù) DataPage ,并在適當(dāng)?shù)臅r候加載數(shù)據(jù),讀取我們需要頁的數(shù)據(jù)。
?
?*?A?special?type?of?JSF?DataModel?to?allow?a?datatable?and?datascroller?to?page
?*?through?a?large?set?of?data?without?having?to?hold?the?entire?set?of?data?in
?*?memory?at?once.
?*?<p>
?*?Any?time?a?managed?bean?wants?to?avoid?holding?an?entire?dataset,?the?managed
?*?bean?should?declare?an?inner?class?which?extends?this?class?and?implements
?*?the?fetchData?method.?This?method?is?called?as?needed?when?the?table?requires
?*?data?that?isn't?available?in?the?current?data?page?held?by?this?object.
?*?<p>
?*?This?does?require?the?managed?bean?(and?in?general?the?business?method?that
?*?the?managed?bean?uses)?to?provide?the?data?wrapped?in?a?DataPage?object?that
?*?provides?info?on?the?full?size?of?the?dataset.
? */
public ? abstract ? class ?PagedListDataModel? extends ?DataModel
{
???? int ?pageSize;
???? int ?rowIndex;
????DataPage?page;
???? /**
?????*?Create?a?datamodel?that?pages?through?the?data?showing?the?specified
?????*?number?of?rows?on?each?page.
????? */
???? public ?PagedListDataModel( int ?pageSize)
???? {
???????? super ();
???????? this .pageSize? = ?pageSize;
???????? this .rowIndex? = ? - 1 ;
???????? this .page? = ? null ;
????}
???? /**
?????*?Not?used?in?this?class;?data?is?fetched?via?a?callback?to?the?fetchData
?????*?method?rather?than?by?explicitly?assigning?a?list.
????? */
???? public ? void ?setWrappedData(Object?o)
???? {
???????? if (o? instanceof ?DataPage)
???????? {
???????????? this .page? = ?(DataPage)?o;
????????}
???????? else
???????? {
???????????? throw ? new ?UnsupportedOperationException( " setWrappedData " );
????????}
????}
???? public ? int ?getRowIndex()
???? {
???????? return ?rowIndex;
????}
???? /**
?????*?Specify?what?the?"current?row"?within?the?dataset?is.?Note?that?the
?????*?UIData?component?will?repeatedly?call?this?method?followed?by?getRowData
?????*?to?obtain?the?objects?to?render?in?the?table.
????? */
???? public ? void ?setRowIndex( int ?index)
???? {
????????rowIndex? = ?index;
????}
???? /**
?????*?Return?the?total?number?of?rows?of?data?available?(not?just?the?number?of
?????*?rows?in?the?current?page!).
????? */
???? public ? int ?getRowCount()
???? {
???????? return ?getPage().getDatasetSize();
????}
???? /**
?????*?Return?a?DataPage?object;?if?one?is?not?currently?available?then?fetch
?????*?one.?Note?that?this?doesn't?ensure?that?the?datapage?returned?includes
?????*?the?current?rowIndex?row;?see?getRowData.
????? */
???? private ?DataPage?getPage()
???? {
???????? if ?(page? != ? null )
???????? {
???????????? return ?page;
????????}
???????? int ?rowIndex? = ?getRowIndex();
???????? int ?startRow? = ?rowIndex;
???????? if ?(rowIndex? == ? - 1 )
???????? {
???????????? // ?even?when?no?row?is?selected,?we?still?need?a?page
???????????? // ?object?so?that?we?know?the?amount?of?data?available.
????????????startRow? = ? 0 ;
????????}
???????? // ?invoke?method?on?enclosing?class
????????page? = ?fetchPage(startRow,?pageSize);
???????? return ?page;
????}
???? /**
?????*?Return?the?object?corresponding?to?the?current?rowIndex.?If?the?DataPage
?????*?object?currently?cached?doesn't?include?that?index?then?fetchPage?is
?????*?called?to?retrieve?the?appropriate?page.
????? */
???? public ?Object?getRowData()
???? {
???????? if ?(rowIndex? < ? 0 )
???????? {
???????????? throw ? new ?IllegalArgumentException(
???????????????????? " Invalid?rowIndex?for?PagedListDataModel;?not?within?page " );
????????}
???????? // ?ensure?page?exists;?if?rowIndex?is?beyond?dataset?size,?then
???????? // ?we?should?still?get?back?a?DataPage?object?with?the?dataset?size
???????? // ?in?it
???????? if ?(page? == ? null )
???????? {
????????????page? = ?fetchPage(rowIndex,?pageSize);
????????}
???????? int ?datasetSize? = ?page.getDatasetSize();
???????? int ?startRow? = ?page.getStartRow();
???????? int ?nRows? = ?page.getData().size();
???????? int ?endRow? = ?startRow? + ?nRows;
???????? if ?(rowIndex? >= ?datasetSize)
???????? {
???????????? throw ? new ?IllegalArgumentException( " Invalid?rowIndex " );
????????}
???????? if ?(rowIndex? < ?startRow)
???????? {
????????????page? = ?fetchPage(rowIndex,?pageSize);
????????????startRow? = ?page.getStartRow();
????????}
???????? else ? if ?(rowIndex? >= ?endRow)
???????? {
????????????page? = ?fetchPage(rowIndex,?pageSize);
????????????startRow? = ?page.getStartRow();
????????}
???????? return ?page.getData().get(rowIndex? - ?startRow);
????}
???? public ?Object?getWrappedData()
???? {
???????? return ?page.getData();
????}
???? /**
?????*?Return?true?if?the?rowIndex?value?is?currently?set?to?a?value?that
?????*?matches?some?element?in?the?dataset.?Note?that?it?may?match?a?row?that?is
?????*?not?in?the?currently?cached?DataPage;?if?so?then?when?getRowData?is
?????*?called?the?required?DataPage?will?be?fetched?by?calling?fetchData.
????? */
a
- 2009-04-16 15:56
- 瀏覽 459
- 評論(0)
- 相關(guān)推薦
發(fā)表評論
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

評論