springmvc 分頁查詢的簡單實現

目前較常用的分頁實現辦法有兩種:
 
  1.每次翻頁都修改SQL,向SQL傳入相關參數去數據庫實時查出該頁的數據並顯示。
 
  2.查出數據庫某張表的全部數據,再通過在業務邏輯裏面進行處理去取得某些數據並顯示。
 
  對於數據量並不大的簡單的管理系統而言,第一種實現方法相對來說容易使用較少的代碼實現分頁這一功能,本文也正是爲大家介紹這種方法:
 
代碼片段:
1,Page.java
package com.cm.contract.common;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;



/**分頁類
 * @author FENGWEI
 * @date 2016-5-23
 */
public class Page implements java.io.Serializable{
	
	private static final long serialVersionUID = 1L;
	//前一頁
	private Boolean hasPrePage;
	//後一頁
	private Boolean hasNextPage;
	//每頁顯示多少條:默認20條
	private Long everyPage = 20L;
	//總頁數
	private Long totalPage;
	//當前第多少頁:默認第1頁
	private Long currentPage = 1L;
	//開始下標
	private Long beginIndex;
	//結束下標
	private Long endinIndex;
	//總共多少條
	private Long totalCount;	
	//排序列名
	private String sortName;	
	//排序狀態
	private String sortState;	
	//排序信息
	private String sortInfo;
	//是否排序
	private Boolean sort = false;
	private String defaultInfo = "  ";
	
	
	
	public String getDefaultInfo() {
		return defaultInfo;
	}

	public void setDefaultInfo(String defaultInfo) {
		this.defaultInfo = defaultInfo;
	}

	public String getSortInfo() {
		return sortInfo;
	}

	public void setSortInfo(String sortInfo) {
		this.sortInfo = sortInfo;
	}

	public String getSortName() {
		return sortName;
	}

	public void setSortName(String sortName) {
		setPageSortState(sortName);		
	}

	public String getSortState() {
		return sortState;
	}

	public void setSortState(String sortState) {
		this.sortState = sortState;
	}

	
	public Page() {
	}

	/**
	 * 常用,用於計算分頁
	 * */
	public Page(Long totalRecords){		
		this.totalCount = totalRecords;
		setTotalPage(getTotalPage(totalRecords));     
	}
	
	/**
	 * 設置每頁顯示多少條時使用
	 * */
	public Page(Long everyPage,Long totalRecords){	
		this.everyPage = everyPage;
		this.totalCount = totalRecords;
		setTotalPage(getTotalPage(totalRecords));     
	}
	
	/**
	 * @param state   狀態碼
	 * @param value   到第多少頁或者設置每頁顯示多少條或者爲排序列名
	 */
	public void pageState(int  index,String value) {				
		sort = false;
		switch (index) {
		case 0 :setEveryPage(Long.parseLong(value));break;
		case 1 :first();break;
		case 2:	previous();break;
		case 3:	next();break;
		case 4: last();break;
		case 5: sort = true;sort(value);break;
		case 6 ://到指定第多少頁
			setCurrentPage(Long.parseLong(value));
			break;			
		}
	}

	/**
	 * 最前一頁
	 */
	private void first() {
		currentPage = 1L;
	}

	private void previous() {
		currentPage--;
	}

	private void next() {
		currentPage++;
	}

	private void last() {
		currentPage = totalPage;
	}

	private void sort(String sortName) {		
		//設置排序狀態
		setPageSortState(sortName);		
	}
		
	
	
	/**
	 * 計算總頁數
	 * */
	private Long getTotalPage(Long totalRecords) {
	     Long totalPage = 0L;	 
	     everyPage = everyPage == null ? 10L : everyPage;
	     if (totalRecords % everyPage == 0)
	       totalPage = totalRecords / everyPage;
	     else {
	       totalPage = totalRecords / everyPage + 1;
	     }
	     return totalPage;
	}	
	

	public Long getBeginIndex() {
		this.beginIndex = (currentPage - 1) * everyPage;
		return this.beginIndex;
	}

	public void setBeginIndex(Long beginIndex) {
		this.beginIndex = beginIndex;
	}

	public Long getCurrentPage() {
		this.currentPage = currentPage == 0 ? 1 : currentPage;
		return this.currentPage;
	}

	public void setCurrentPage(Long currentPage) {
		if(0 == currentPage){
			currentPage = 1L;
		}
		this.currentPage = currentPage;
	}

	public Long getEveryPage() {
		this.everyPage = everyPage == 0 ? 10 : everyPage;
		return this.everyPage;
	}

	public void setEveryPage(Long everyPage) {		
		this.everyPage = everyPage;
	}

	public Boolean getHasNextPage() {
		this.hasNextPage = (currentPage != totalPage) && (totalPage != 0);
		return this.hasNextPage;
	}

	public void setHasNextPage(Boolean hasNextPage) {
		this.hasNextPage = hasNextPage;
	}

	public Boolean getHasPrePage() {
		this.hasPrePage = currentPage != 1;
		return this.hasPrePage;
	}

	public void setHasPrePage(Boolean hasPrePage) {
		this.hasPrePage = hasPrePage;
	}

	public Long getTotalPage() {
		return this.totalPage;
	}

	public void setTotalPage(Long totalPage) {
		if(this.currentPage > totalPage){
			this.currentPage = totalPage;
		}
		this.totalPage = totalPage;
	}

	public Long getTotalCount() {
		return this.totalCount;
	}

	public void setTotalCount(Long totalCount) {
		setTotalPage(getTotalPage(totalCount));  
		this.totalCount = totalCount;
	}

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this);
	}
	
	/**
	 * 設置排序狀態
	 * */
	private void setPageSortState(String newPageSortName){		
		//判斷之前的排序字段是否爲空
		if(StringUtils.isEmpty(sortName)){
			//默認排序爲升序
			this.sortState = PageUtil.ASC;		
			this.sortInfo = PageUtil.PAGE_ASC;						
		}else{
			if(StringUtils.equalsIgnoreCase(newPageSortName, sortName)){
				//判斷sortState排序狀態值
				if(StringUtils.equalsIgnoreCase(sortState, PageUtil.ASC)){
					this.sortState = PageUtil.DESC;
					this.sortInfo = PageUtil.PAGE_DESC;								
				}else{
					this.sortState = PageUtil.ASC;
					this.sortInfo = PageUtil.PAGE_ASC;					
				}				
			}else{
				//默認
				this.sortState = PageUtil.ASC;		
				this.sortInfo = PageUtil.PAGE_ASC;
			}
		}
		sortName = newPageSortName.toLowerCase();			
	}

	public Boolean isSort() {
		return sort;
	}

	public void setSort(Boolean sort) {
		this.sort = sort;
	}


	public Long getEndinIndex() {
		this.endinIndex = (currentPage) * everyPage;
		return endinIndex;
	}

	public void setEndinIndex(Long endinIndex) {
		this.endinIndex = endinIndex;
	}	
}
2.PageState.java
package com.cm.contract.common;

import org.apache.commons.lang.StringUtils;




/**分頁狀態類
 * @author FENGWEI
 * @date 2016-5-23
 */
public enum PageState {
	
	/**
	 * 設置每頁顯示多少條
	 * */
	SETPAGE,
	/**
	 * 首頁
	 * */
	FIRST, 
	/**
	 * 向前一頁
	 * */
	PREVIOUS, 
	/**
	 * 向後一頁
	 * */
	NEXT, 
	/**
	 * 末頁
	 * */
	LAST, 
	/**
	 * 排序
	 * */
	SORT,
	/**
	 * 到第多少頁
	 * */
	GOPAGE;

	
	/**
	 * @param value 索引名稱
	 * @return 返回索引下標
	 */
	public static int getOrdinal(String value) {
		int index = -1;
		if (StringUtils.isEmpty(value)) {
			return index;
		}
		String newValue = StringUtils.trim(value).toUpperCase();
		try {
			index = valueOf(newValue).ordinal();
		} catch (IllegalArgumentException e) {}
		return index;
	}
}

3.PageUtil.java
/**
 * 分頁工具類
 * @author FENGWEI
 * @date 2016-5-23
 */
public class PageUtil {
	
	public static final String ASC = "asc";
	public static final String DESC = "desc";
	public static final String PAGE_DESC = "↓";
	public static final String PAGE_ASC = "↑";
	public static final String PAGE_NULL = "  ";	
	public static final String SESSION_PAGE_KEY = "page";	
	
	
	/**
	 * 初始化分頁類
	 * @param initPageSql  未分頁的查詢SQL
	 * @param totalCount   總行數
	 * @param index        分頁狀態
	 * @param value        只有在設置每頁顯示多少條時,值不會NULL,其它爲NULL
	 */
	public  static Page inintPage(Long totalCount,Integer index,String value,Page sessionPage){	
		Page page = null;
		if(index < 0){
			 page = new Page(totalCount);
		}else{
			 /**每頁顯示多少條*/
			 Long everPage = null == value ? 10 : Long.parseLong(value);
			 /**獲取Session中的分頁類,方便保存頁面分頁狀態*/
			 page = sessionPage;			 
			 page.setEveryPage(everPage);
			 page.setTotalCount(totalCount);			
		}	
		return page;		
	}
	
	

	
	/**
	 * 當頁點擊:首頁,前一頁,後一頁,末頁,排序,到第多少頁時進行分頁操作
	 * @param index 分頁狀態
	 * @param value 排序字段名或者到第多少頁
	 */
	public static Page execPage(int  index,String value,Page sessionPage){	
		Page page = sessionPage;			
		/**調用方法進行分頁計算*/
		page.pageState(index,value);		
		return page;		
	}

}

4.DefaultController.java  此部分可以靈活使用
package com.cm.contract.common;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.bind.annotation.ModelAttribute;

/**
 * 提取公用的request和response Title:DefaultController Descrption:
 * 
 * @author FENGWEI
 * @date 2016-5-6下午3:30:32
 */
public class DefaultController  {

	/**
	 * oracel的三層分頁語句 子類在展現數據前,進行分頁計算!
	 * 
	 * @param querySql
	 *            查詢的SQL語句,未進行分頁
	 * @param totalCount
	 *            根據查詢SQL獲取的總條數
	 * @param columnNameDescOrAsc
	 *            列名+排序方式 : ID DESC or ASC
	 */
	protected Page executePage(HttpServletRequest request, Long totalCount) {
		if (null == totalCount) {
			totalCount = 0L;
		}
		/** 頁面狀態,這個狀態是分頁自帶的,與業務無關 */
		String pageAction = request.getParameter("pageAction");
		String value = request.getParameter("pageKey");

		/** 獲取下標判斷分頁狀態 */
		int index = PageState.getOrdinal(pageAction);

		Page page = null;
		/**
		 * index < 1 只有二種狀態 1 當首次調用時,分頁狀態類中沒有值爲 NULL 返回 -1 2 當頁面設置每頁顯示多少條:
		 * index=0,當每頁顯示多少條時,分頁類要重新計算
		 * */
		Page sessionPage = getPage(request);

		if (index < 1) {
			page = PageUtil.inintPage(totalCount, index, value, sessionPage);
		} else {
			page = PageUtil.execPage(index, value, sessionPage);
		}
		setSession(request, page);
		return page;
	}

	private Page getPage(HttpServletRequest request) {
		Page page = (Page) request.getSession().getAttribute(
				PageUtil.SESSION_PAGE_KEY);
		if (page == null) {
			page = new Page();
		}
		return page;
	}

	private void setSession(HttpServletRequest request, Page page) {
		request.getSession().setAttribute(PageUtil.SESSION_PAGE_KEY, page);
	}
}

使用方法:
5,Controller.java 
/**
	 * model 添加的分頁條件
	 *  executePage 方法寫在工具類中
	 * @param model
	 */
@Controller
public class CMLogController extends DefaultController {
@RequestMapping("index.do")
	public ModelAndView userInto(ModelMap model, String username) {
		nameStr = username;
		model.addAttribute("username", nameStr);
		// 分頁數
		Long totalCount = logService.pageCounts(model);
		// 分頁顯示
		Page page = executePage(request, totalCount);
		if (page.isSort()) {
			model.put("orderName", page.getSortName());
			model.put("descAsc", page.getSortState());
		} else {
			model.put("orderName", "logtime");
			model.put("descAsc", "desc");
		}
		model.put("startIndex", page.getBeginIndex());
		model.put("endIndex", page.getEndinIndex());
		ModelAndView mv = new ModelAndView();
		// 分頁查詢
		logList = logService.pageList(model);
		mv.addObject("logList", logList);
		mv.setViewName("/jsp/log");
		return mv;
	}}
6.maybatis中幾條查詢語句
//分頁查詢
<select id="pageList" parameterType="map"  resultMap="BaseResultMap">   
       
       select ttt.* from(select tt.*,rownum rn from(select * from CM_LOG
    	<where>     	   
		   <if test="username != null and username != ''">
		       <!-- 
		          特別提醒一下, $只是字符串拼接, 所以要特別小心sql注入問題。
		          在開發時使用: $,方便調試sql,發佈時使用: #
		       -->
		       and username like '%${username}%' 				   
		   </if>
		     <if test="type != null and type != ''">
		       <!-- 
		          特別提醒一下, $只是字符串拼接, 所以要特別小心sql注入問題。
		          在開發時使用: $,方便調試sql,發佈時使用: #
		       -->
		       AND TYPE = #{type,jdbcType=VARCHAR}	   
		   </if>
		 </where>  
		 order by ${orderName} ${descAsc} )tt)ttt
		 <where> 
		   <if test="startIndex != null and startIndex != ''">
		       rn > ${startIndex}  				   
		   </if>	
		   	<if test="endIndex != null and endIndex != ''">		   	   
		         <![CDATA[ and rn <= ${endIndex}  ]]> 			        		   
		    </if>    
		 </where>		 	 
</select>
// 分頁數
  <select id="pageCounts" parameterType="map" resultType="long">   
   select count(*) from CM_LOG 
   <where> 
   <if test="username != null and username != ''">
        and username like '%${username}%' 				   
   </if>	
   </where>  
</select>

7.前臺頁面index.jsp
//只需在頁面佈局添加該div
	//username 爲條件 
	//	<jsp:param name="url" value="/log/index.do?"/>		不帶條件的方式 問號必須存在
<body >
	<div align="right" style="height: 20">
			<jsp:include page="/jsp/page.jsp">
					<jsp:param name="url" value="/log/index.do?username=${username }"/>		

				</jsp:include>
		</div>

		</body >

8,引用的Page.jsp
	<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="page" value="${sessionScope.page}" />
<c:set var="path" value="${pageContext.request.contextPath}" />
<c:set var="url" value="${param.url}" />
<c:set var="urlParams" value="${param.urlParams}" />
<c:set var="pathurl" value="${path}/${url}" />
<tr>
	<td colspan="5">
	${urlParams }
		共${page.totalCount}條記錄 共${page.totalPage}頁 每頁顯示${page.everyPage}條
		當前第${page.currentPage}頁 
		<c:choose>
			<c:when test="${page.hasPrePage eq false}">
 			    <<首頁 <上頁 
 			</c:when>
			<c:otherwise>
				<a href="${pathurl}&pageAction=first${urlParams}"><<首頁 </a> 
				<a href="${pathurl}&pageAction=previous${urlParams}" /><上一頁</a>
			</c:otherwise>
		</c:choose>
		 || 
		<c:choose>
			<c:when test="${page.hasNextPage eq false}">
 			     下頁> 尾頁>>
 			</c:when>
			<c:otherwise>
				<a href="${pathurl}&pageAction=next${urlParams}">下一頁> </a> 
				<a href="${pathurl}&pageAction=last${urlParams}">末頁>></a>
			</c:otherwise>
		</c:choose>
		 
		<SELECT name="indexChange" id="indexChange"
			onchange="getCurrentPage(this.value);">
			<c:forEach var="index" begin="1" end="${page.totalPage}" step="1">
				<option value="${index}" ${page.currentPage eq index ? "selected" : ""}>
					第${index}頁
				</option>
			</c:forEach>
		</SELECT>
		 
		每頁顯示:<select name="everyPage" id="everyPage" onchange="setEveryPage(this.value);">
			       <c:forEach var="pageCount" begin="5" end="${page.totalCount}" step="5">			       	    
						<option value="${pageCount}" ${page.everyPage eq pageCount ? "selected" : ""}>
							${pageCount}條
						</option>
					</c:forEach>
		       </select>
	</td>
</tr>
<div style='display: none'>
	<a class=listlink id="indexPageHref" href='#'></a>
</div>
<script>
function getCurrentPage(index){	
	var a = document.getElementById("indexPageHref");	
	a.href = '${pathurl}&pageAction=gopage&pageKey='+index+'${urlParams}';        
    a.setAttribute("onclick",'');          
    a.click("return false");   
}
function setEveryPage(everyPage){	
	var a = document.getElementById("indexPageHref");
	var currentPage = document.getElementById('indexChange').value;
	a.href = '${pathurl}&pageAction=setpage&pageKey='+everyPage+'${urlParams}';       
    a.setAttribute("onclick",'');          
    a.click("return false");   
}
function sortPage(sortName){	
	var a = document.getElementById("indexPageHref");	
	a.href = '${pathurl}&pageAction=sort&pageKey='+sortName+'${urlParams}';      
    a.setAttribute("onclick",'');      
    a.click("return false");   
}
</script>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章