1. 程式人生 > >李曉潔 廊坊師範學院資訊科技提高班 12期

李曉潔 廊坊師範學院資訊科技提高班 12期

       在開發過程中,我們經常會從資料庫中查詢資料,然後在客戶端顯示出來。當資料少時,可以在一個頁面顯示。當我們查詢幾百條以上資料,直接顯示在一個頁面上,不僅瀏覽不方便,查詢效率也會受到影響,這是,我們就可以使用分頁查詢來解決這個問題。

分頁思路

       

         分析上面這個頁面,想要實現分頁,我們在頁面中需要顯示的資料有:

本頁的資料列表

recordList

當前頁

currentPage

總頁數

pageCount

每頁顯示多少條

pageSize

總記錄數

recordCount

頁碼列表的開始索引

beginPageIndex

頁碼列表的結束索引

endPageIndex

        實現分頁需要顯示這麼多資料,所以我們就可以為分頁功能來封裝一個PageBean實體,用來接收頁面傳來的引數,以及為action提供從資料庫查詢出來的資料。

        我們可以把頁面顯示的資料分為三類:

1.指定的或是頁面引數:currentPage,pageSize.

2.資料庫查詢的資料:recordCount,recordList.

3.通過計算得到:pageCount,beginPageIndex,endPageIndex.

        這樣就可以只接收前4個必要的屬性,自動計算出其他3個屬性的值。

我們可以先分析一下大概的思路,首先JSP頁面負責顯示資料,Action用來接收頁面傳來的引數,並呼叫Service準備需要的資料,Service實現了資料訪問的功能,從資料庫中查詢出需要的資料,通過封裝的PageBean實體返回給Action。


程式碼實現

PageBean:

/** 分頁功能中一頁的資訊 */
public class PageBean {

	//指定的或是頁面引數
	private int currentPage;//當前頁
	private int pageSize;//每頁顯示多少條
	
	//查詢資料庫
	private int recordCount;//總記錄數
	private List recordList;//本頁的資料列表
	
	//計算
	private int pageCount;//總頁數
	private int beginPageIndex;//頁碼列表的開始索引
	private int endPageIndex;//頁碼列表的結束索引
	
	/**
	 * 只接受前4個必要的屬性,會自動計算出其他3個屬性的值
	 * @param currentPage
	 * @param pageSize
	 * @param recordCount
	 * @param recordList
	 */
	public PageBean(int currentPage, int pageSize, int recordCount,
			List recordList) {
		this.currentPage = currentPage;
		this.pageSize = pageSize;
		this.recordCount = recordCount;
		this.recordList = recordList;
		
		//計算總頁碼
		pageCount = (recordCount + pageSize - 1) / pageSize;
		
		//計算beginPageIndex 和 endPageIndex		
		//>>總頁數不多於10頁,則全部顯示
		if(pageCount <= 10){
			beginPageIndex = 1;
			endPageIndex = pageCount;
		}
		//總頁數多於10頁,則顯示當前頁附近的共10個頁碼
		else{
			//當前頁附近的共10個頁碼(前4個+當前頁+後5個)
			beginPageIndex = currentPage - 4;
			endPageIndex = currentPage + 5;
			
			//當前面的頁碼不足4個時,則顯示前10個頁碼
			if(beginPageIndex < 1){
				beginPageIndex = 1;
				endPageIndex = 10;
			}
			//當後面的頁碼不足5個時,則顯示後10個頁碼
			if(endPageIndex > pageCount){
				endPageIndex = pageCount;
				beginPageIndex = pageCount -10 + 1;
			}
		}
			
	}
	
	//這裡是get,set 
}

Action中準備分頁資訊的程式碼

    // ===========分頁用的引數============
    private int pageNum = 1;// 當前頁
    private int pageSize = 10;// 每頁顯示多少條記錄
    //這裡省略了get,set方法
    // 準備分頁資訊(將pageBean放在棧頂)
    PageBean pageBean = replyService.getPageBeanByTopic(pageNum,pageSize,topic);
    ActionContext.getContext().getValueStack().push(pageBean);
Service中查詢資料庫的程式碼
       public PageBean getPageBeanByForum(int pageNum, int pageSize, Forum forum) {
		// 查詢列表
		List list = getSession()
				.createQuery(//
						"FROM Topic t WHERE t.forum=? ORDER BY (CASE t.type WHEN 2 THEN 2 ELSE 0 END) DESC, t.lastUpdateTime DESC")//
				.setParameter(0, forum)//
				.setFirstResult((pageNum - 1) * pageSize)//
				.setMaxResults(pageSize)//
				.list();

		// 查詢總記錄數量
		Long count = (Long) getSession().createQuery(//
				"SELECT COUNT(*) FROM Topic t WHERE t.forum=?")//
				.setParameter(0, forum)//
				.uniqueResult();

		return new PageBean(pageNum, pageSize, count.intValue(), list);
	}
JSP頁面接收資料(這裡只顯示了分頁控制元件的實現,當前頁顯示的資料列表recordList繫結到對應的位置就可以了。):
<!--分頁資訊-->
<div id=PageSelectorBar>
	<div id=PageSelectorMemo>頁次:${currentPage}/${pageCount}頁  
		每頁顯示:${pageSize}條   總記錄數:${recordCount}條</div>
	<div id=PageSelectorSelectorArea>

		<a href="javascript:gotoPage(1)" title="首頁" style="cursor: hand;">
			<img
			src="${pageContext.request.contextPath}/style/blue/images/pageSelector/firstPage.png" />
		</a>

		<s:iterator begin="%{beginPageIndex}" end="%{endPageIndex}" var="num">
			<s:if test="#num == currentPage">
				<%-- #表示從map獲取 --%>
				<%-- 當前頁 --%>
				<span class="PageSelectorNum PageSelectorSelected">${num}</span>
			</s:if>
			<s:else>
				<%-- 非當前頁 --%>
				<span class="PageSelectorNum" style="cursor: hand;"
					onClick="gotoPage(${num});">${num}</span>
			</s:else>
		</s:iterator>

		<a href="javascript:gotoPage(${pageCount})" title="尾頁"
			style="cursor: hand;"> <img
			src="${pageContext.request.contextPath}/style/blue/images/pageSelector/lastPage.png" />
		</a> 轉到: <select onchange="gotoPage(this.value)" id="_pn">
			<s:iterator begin="1" end="%{pageCount}" var="num">
				<option value="${num}">${num}</option>
			</s:iterator>
		</select>
		<script type="text/javascript">
			$("#_pn").val("${currentPage}");
		</script>
	</div>
</div>

   到現在,我們已經實現了一個簡單的分頁查詢功能。那麼我們繼續想,如果我們其他頁面實現分頁查詢功能,還需要再copy一遍上面的程式碼嗎?這麼做顯然不是科學的方法,我們就會繼續封裝一些公共的程式碼,靈活的供各個功能呼叫。比如說現在能想到的優化的地方:

1.action中公共的分頁引數

2.Service中除了查詢的Hql語句和引數不同,具體的套路都差不多,我們可不可以傳遞hql和對應的引數,呼叫一個公共的方法?

3.JSP頁面上相同的分頁程式碼,寫在一個公共的頁面中,需要分頁時,直接引用這個頁面就好了。