原創地址: http://www.cnblogs.com/Alandre/ (泥沙磚瓦漿木匠),須要轉載的,保留下! Thanks java
學習的心態第一,解行要相應。其實《弟子規》在「餘力學文」當中,一開頭就強調了這一個重點。「不力行,但學文,長浮華,成何人」,這個沒有僥倖的,只要學了不去作,無形當中就會增加傲慢,本身不知道。-<弟子規>spring
JAVA-Web 基礎那塊,我本身也準備.搞哪裏,優化哪裏而後帶給你們終結.謝謝sql
分頁雖易,好卻難.數據量,怎麼辦?apache
分頁(Paging),就像個切面.能把這個切面好好的放進去也是種nice方式.api
第一種:小數據量分頁實現 (可普遍用於 門戶型 網頁快速開發等)app
這種比較簡單,這邊咱們模擬實現.ide
字段結構:函數
private int pageSize; //每頁有多少條工具
private int rowCount; //總行數 post
private int pageCount;//總頁數
private int currentPage; //當前頁碼
流程結構:
subList(int fromIndex, int toIndex)
返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之間的部分視圖。
分頁工具類:
package jeffli_10; import java.util.ArrayList; import java.util.List; /** 分頁類:根據總記錄數和分頁大小對 {@link List} 進行分頁處理 */ public class Pagination { public static final int DEFAULT_PAGE_SIZE = 10; private int rowCount; private int currentPage; private int pageSize; private int pageCount; private List<?> list; public Pagination(List<?> list) { this(list, DEFAULT_PAGE_SIZE); } public Pagination(List<?> list, int pageSize) { this.currentPage = 1; this.list = list; this.rowCount = list.size(); setPageSize(pageSize); } private void adjustPageCount() { pageCount = (rowCount + pageSize - 1) / pageSize; } /** 獲取要分頁的 {@link List} */ public List<?> getList() { return list; } /** 獲取的 {@link List} 當前頁內容 */ public List<?> getCurrentList() { List<?> currentList = null; if(currentPage >= 1 && currentPage <= pageCount) { int index = (currentPage - 1) * pageSize; currentList = list.subList(index, (currentPage < pageCount) ? (index + pageSize) : rowCount); } return currentList; } /** 獲取當前頁號(從 1 開始) */ public int getCurrentPage() { return currentPage; } /** 設置當前頁號(從 1 開始) */ public boolean setCurrentPage(int page) { if(page >= 1 && page <= pageCount) { currentPage = page; return true; } return false; } /** 轉到下一頁 */ public boolean nextPage() { return setCurrentPage(currentPage + 1); } /** 轉到上一頁 */ public boolean prePage() { return setCurrentPage(currentPage - 1); } /** 獲取分頁大小 */ public int getPageSize() { return pageSize; } /** 設置分頁大小 */ public void setPageSize(int size) { if(size <= 0) size = DEFAULT_PAGE_SIZE; int index = (currentPage - 1) * pageSize; pageSize = size; if(index > pageSize) currentPage = (index + pageSize - 1) / pageSize; else currentPage = 1; adjustPageCount(); } /** 獲取總頁數 */ public int getPageCount() { return pageCount; } public static void main(String[] args) { final int PAGE_SIZE = 10; final int LIST_SIZE = 39; List<Integer> list = new ArrayList<Integer>(); for(int i = 1; i <= LIST_SIZE; i++) list.add(i); Pagination pg = new Pagination(list, PAGE_SIZE); for(int i = 1; i <= pg.getPageCount(); i++) { pg.setCurrentPage(i); System.out.println(pg.getCurrentList()); } } }
RUN,你會看到 OUTPUTS:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [11, 12, 13, 14, 15, 16, 17, 18, 19, 20] [21, 22, 23, 24, 25, 26, 27, 28, 29, 30] [31, 32, 33, 34, 35, 36, 37, 38, 39]
環境:
spring MVC (spring-4.0.0.RELEASE.jar)
hibernate (hibernate-core-4.3.5.Final.jar)
Mysql
兩個核心工具類-分頁
分頁對象,包含所須要的全部參數及邏輯.
package sedion.jeffli.wmuitp.util; import java.util.List; import org.apache.commons.lang3.StringUtils; import com.google.common.collect.Lists; public class Page<T> { //public variables public static final String ASC = "asc"; public static final String DESC = "desc"; //parameters of page protected int pageNo = 1; protected int pageSize = -1; protected String orderBy = null; protected String order = null; protected boolean autoCount = true; //results protected long totalCount = -1; protected List<T> result = Lists.newArrayList(); public Page() { } public Page(int pageSize) { this.pageSize = pageSize; } /** * 得到當前頁的頁號,序號從1開始,默認爲1. */ public int getPageNo() { return pageNo; } /** * 設置當前頁的頁號,序號從1開始,低於1時自動調整爲1. */ public void setPageNo(final int pageNo) { this.pageNo = pageNo; if (pageNo < 1) this.pageNo = 1; } /** * 返回Page對象自身的setPageNo函數,可用於連續設置。 */ public Page<T> pageNo(final int thePageNo) { setPageNo(thePageNo); return this; } /** * 得到每頁的記錄數量, 默認爲-1. */ public int getPageSize() { return pageSize; } /** * 設置每頁的記錄數量. */ public void setPageSize(final int pageSize) { this.pageSize = pageSize; } /** * 返回Page對象自身的setPageSize函數,可用於連續設置。 */ public Page<T> pageSize(final int thePageSize) { setPageSize(thePageSize); return this; } /** * 根據pageNo和pageSize計算當前頁第一條記錄在總結果集中的位置,序號從1開始. */ public int getFirst() { return ((pageNo - 1) * pageSize) + 1; } /** * 得到排序字段,無默認值. 多個排序字段時用','分隔. */ public String getOrderBy() { return orderBy; } /** * 設置排序字段,多個排序字段時用','分隔. */ public void setOrderBy(final String orderBy) { this.orderBy = orderBy; } /** * 返回Page對象自身的setOrderBy函數,可用於連續設置。 */ public Page<T> orderBy(final String theOrderBy) { setOrderBy(theOrderBy); return this; } /** * 得到排序方向, 無默認值. */ public String getOrder() { return order; } /** * 設置排序方式向. * * @param order * 可選值爲desc或asc,多個排序字段時用','分隔. */ public void setOrder(final String order) { String lowcaseOrder = StringUtils.lowerCase(order); String[] orders = StringUtils.split(lowcaseOrder, ','); for (String orderStr : orders) { if (!StringUtils.equals(DESC, orderStr) && !StringUtils.equals(ASC, orderStr)) {// 檢查order字符串的合法值 throw new IllegalArgumentException("排序方向" + orderStr + "不是合法值"); } } this.order = lowcaseOrder; } /** * 返回Page對象自身的setOrder函數,可用於連續設置。 */ public Page<T> order(final String theOrder) { setOrder(theOrder); return this; } /** * 是否已設置排序字段,無默認值. */ public boolean isOrderBySetted() { return (StringUtils.isNotBlank(orderBy) && StringUtils.isNotBlank(order)); } /** * 得到查詢對象時是否先自動執行count查詢獲取總記錄數, 默認爲false. */ public boolean isAutoCount() { return autoCount; } /** * 設置查詢對象時是否自動先執行count查詢獲取總記錄數. */ public void setAutoCount(final boolean autoCount) { this.autoCount = autoCount; } /** * 返回Page對象自身的setAutoCount函數,可用於連續設置。 */ public Page<T> autoCount(final boolean theAutoCount) { setAutoCount(theAutoCount); return this; } // -- 訪問查詢結果函數 --// /** * 得到頁內的記錄列表. */ public List<T> getResult() { return result; } /** * 設置頁內的記錄列表. */ public void setResult(final List<T> result) { this.result = result; } /** * 得到總記錄數, 默認值爲-1. */ public long getTotalCount() { return totalCount; } /** * 設置總記錄數. */ public void setTotalCount(final long totalCount) { this.totalCount = totalCount; } /** * 根據pageSize與totalCount計算總頁數, 默認值爲-1. */ public long getTotalPages() { if (totalCount < 0) return 1; long count = totalCount / pageSize; if (totalCount % pageSize > 0) count++; return count; } /** * 是否還有下一頁. */ public boolean isHasNext() { return (pageNo + 1 <= getTotalPages()); } /** * 取得下頁的頁號, 序號從1開始. 當前頁爲尾頁時仍返回尾頁序號. */ public int getNextPage() { if (isHasNext()) return pageNo + 1; else return pageNo; } /** * 是否還有上一頁. */ public boolean isHasPre() { return (pageNo - 1 >= 1); } /** * 取得上頁的頁號, 序號從1開始. 當前頁爲首頁時返回首頁序號. */ public int getPrePage() { if (isHasPre()) return pageNo - 1; else return pageNo; } public long getBegin() { return Math.max(1, getPageNo() - pageSize / 2); } public long getEnd() { return getTotalPages(); } }
分頁初始化(包括參數變化)
package sedion.jeffli.wmuitp.util; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import com.sun.org.apache.xml.internal.resolver.helpers.PublicId; import sedion.jeffli.wmuitp.entity.SubjectInfor; /** * 分頁工具 * */ public class PageUtil { public static int PAGE_SIZE = 20; public static int MAX_SIZE = 9999; public static final String PAGE_NUM_STR = "pageNum"; /** * 初始化分頁 * @param page page對象 * @param request 請求體 * @return */ public static int[] init(Page<?> page, HttpServletRequest request) { int pageNum = Integer.parseInt(StringUtils.defaultIfBlank(request.getParameter(PAGE_NUM_STR), "1")); page.setPageNo(Integer.valueOf(pageNum)); page.setPageSize(page.getPageSize()); int firstResult = page.getFirst() - 1; int maxResults = page.getPageSize(); return new int[] { firstResult, maxResults }; } }
#這裏咱們用request.getParameter(PAGE_NUM_STR) 獲取分頁操做時改變的字段.這樣沒必要要每次都在Controller上附帶參數了.
頁面端:
<form id="pagerForm" method="post" action="${ctx}/subjectInfor/subjectInfors"> <input type="hidden" name="pageNum" value=${page.getPageNo()} /> <input type="hidden" name="numPerPage" value=${page.getPageSize()} /> </form> <div class="panelBar"> <div class="pages"> <span>顯示</span> <select class="combox" name="numPerPage" onchange="navTabPageBreak({numPerPage:this.value})"> <option value="20" <#if numPerPage == 20> selected</#if>>20 </option> <option value="50" <#if numPerPage == 50> selected</#if>>50 </option> <option value="100" <#if numPerPage == 100> selected</#if>>100 </option> <option value="200" <#if numPerPage == 200> selected</#if>>200 </option> </select> <span>條,共${page.getTotalCount()}條</span> </div> <div class="pagination" totalCount=${page.getTotalCount()} numPerPage=${page.getPageSize()} pageNumShown="10" currentPage=${page.getPageNo()}></div>
而後到Controller層:
@RequestMapping(value = "/subjectInfors") public ModelAndView subjectInfos() { ModelAndView mav = new ModelAndView(SubjectInforWebConstant.getSubjectInforListView()); try { Page<SubjectInfor> page = new Page<>(PageUtil.PAGE_SIZE); int[] pageParams = PageUtil.init(page,request);//分頁初始化 subjectInforService.getSubjectInforsPages(page, pageParams); mav.addObject(MainWebConstant.getPage(), page); } catch (Exception e) { e.printStackTrace(); } return mav; }
調用Service層:
@Override public List<SubjectInfor> getSubjectInforsPages(Page<SubjectInfor> page, int[] pageParams) { List<SubjectInfor> results = new ArrayList<>(); StringBuffer resultsHQL = new StringBuffer(All_SUBJECT_INFORS); try { results = subjectInforDAO.findByPage(resultsHQL.toString(), pageParams[0], pageParams[1]); page.setTotalCount(subjectInforDAO.getCount(resultsHQL.toString())); page.setResult(results); } catch (Exception e) { e.printStackTrace(); } return results; }
調用DAO層:
/** * find entity-s of database by hql * -------------------------------------------------------- * @param(String) hql * @param(String) offset 當前標識 * @param(String) pageSize 分頁大小 * @return null/List<T> */ @SuppressWarnings("unchecked") public List<T> findByPage(String hql, int offset, int pageSize) { if (hql == null) { return new ArrayList<T>(); } Query query = createQuery(hql); if (!(offset == 0 && pageSize == 0)) { query.setFirstResult(offset).setMaxResults(pageSize); } if (query.list() != null) return query.list(); else return null; }
實現的效果圖:
#這樣分頁就簡簡單單實現了.
找我加羣,一塊兒共勉!