一、用到的工具類的封裝
為了實現代碼的重用性,我們將經常用到的代碼封裝到工具類中,以便在任何地方都可以調用
1、獲取路徑工具
在jsp頁面中,我們經常會向Servlet發送請求,並通過反射,實現通過傳遞不同的參數,調用Servlet的對應方法
因此,我們在工具類中封裝一個獲取路徑的方法,用於獲取jsp頁面的請求路徑及相關參數
1 public static String getPath(HttpServletRequest request){ 2 String uri=request.getRequestURI(); //返回“項目名/請求Servlet名”的字符串 3 String quString=request.getQueryString(); //獲取請求的參數部分 4 String path=uri+"?"+quString; //拼串,請求地址:項目名/servlet名?參數 5 if(path.contains("&pageNumber")){ 6 //截串,將沒有用的參數截去,只留下用於反射的method參數 7 path=path.substring(0, path.indexOf("&pageNumber")); 8 } 9 return path; 10 }
二、后台分頁的實現
1、bean層:
創建Page實體類:注意Page類要應用泛型,實現可重用
屬性:
private List<T> list; //當前頁列表數據,數據庫查詢得到
private int pageNumber; //當前頁碼,前端頁面傳遞
private int totalRecord; //總記錄數,數據庫查詢得到
private int pageSize; //每頁顯示條數,在Servlet中指定
//private int totalPage; //總頁數,計算得到
//private int index; //當前頁的起始索引,計算得到
private String path; //用來設置Servlet訪問路徑及method參數
方法:
各個屬性對應的get、set方法以及getTotalPage()和getIndex()方法,用來計算總頁數和索引值
1 public class Page<T> { 2 private List<T> list; //當前頁列表數據,數據庫查詢得到
3 private int pageNumber; //當前頁碼,前端頁面傳遞
4 private int totalRecord; //總記錄數,數據庫查詢得到
5 private int pageSize; //每頁顯示條數,前端頁面傳遞 6 //private int totalPage; //總頁數,計算得到 7 //private int index; //當前頁的起始索引,計算
8 private String path; //用來設置Servlet訪問路徑及method參數
9
10 public Page() { 11 super(); 12 } 13
14 public Page(int pageNumber, int totalRecord, int pageSize) { 15 super(); 16 this.pageNumber = pageNumber; 17 this.totalRecord = totalRecord; 18 this.pageSize = pageSize; 19 } 20
21 public List<T> getList() { 22 return list; 23 } 24 public void setList(List<T> list) { 25 this.list = list; 26 } 27 public int getPageNumber() { //控制頁碼不能<1,也不能>totalPage 28 if(pageNumber<1){ 29 pageNumber=1; 30 }else if (pageNumber>getTotalPage()) { 31 pageNumber=getTotalPage(); 32 } 33 return pageNumber; 34 } 35 public void setPageNumber(int pageNumber) { 36 this.pageNumber = pageNumber; 37 } 38 public int getTotalRecord() { 39 return totalRecord; 40 } 41 public void setTotalRecord(int totalRecord) { 42 this.totalRecord = totalRecord; 43 } 44 public int getPageSize() { 45 return pageSize; 46 } 47 public void setPageSize(int pageSize) { 48 this.pageSize = pageSize; 49 } 50 public int getTotalPage() { 51 return (int) Math.ceil((double)getTotalRecord()/getPageSize()); 52 } 53 public int getIndex() { 54 return (getPageNumber()-1)*getPageSize(); //分頁查詢,在數據訪問層一定會調用getIndex方法獲得索引值 55 } //而在getIndex方法中調用了getPageNumber方法,保證了頁碼在正常范圍內 56
57 public String getPath() { 58 return path; 59 } 60
61 public void setPath(String path) { 62 this.path = path; 63 } 64
65 }
2、Servlet層:
創建getPage(req,resp)方法,用來獲取對應頁碼的數據並封裝為Page類的對象
1)通過工具類獲取請求路徑
2)獲取請求頁碼參數
3)調用Service層的getPage方法,獲取請求頁面的信息,並封裝為Page類對象
4)設置Page類對象的path屬性(訪問路徑)
5)通過request.setAttribute("page", page);將頁面信息放入域中
6)將請求轉發到頁面
1 public void getPage(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{ 2 String path=WEBUtils.getPath(request); 3 String pageNumber=request.getParameter("pageNumber"); //獲取頁碼 4 Page<Book> page=new Page<Book>(); 5 page=bookService.getPage(pageNumber,pageSize); //獲取頁面信息 6 page.setPath(path); //設置訪問路徑 7 request.setAttribute("page", page); //將頁面信息放入域中 8 request.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(request, response); 9 }
3、Service層:
1)設置默認頁碼
2)pageNumber類型轉換
3)獲取總記錄數
4)封裝Page類對象
5)獲取當前頁的數據列表並封裝到page中
1 public Page<Book> getPage(String pageNumber,int pageSize) { 2 int pageNo=1; //設置默認頁碼,當pageNumber類型轉換出錯時,會起作用,否則值被覆蓋
3 Page<Book> page=null; 4
5 try { 6 //servlet層獲取的參數類型為string,需要轉換為整型
7 pageNo=Integer.parseInt(pageNumber); 8 } catch (Exception e) { 9 System.out.println("字符串轉換出錯"); 10 } 11 //1.獲取總記錄數
12 int totalRecord=bookDao.getRecordsCount(); 13 //2.封裝page對象
14 page=new Page<Book>(pageNo, totalRecord, pageSize); 15 //3.查詢當前頁對應的數據列表並封裝到page對象中
16 List<Book> list=bookDao.getPageList(page.getIndex(),pageSize); 17 page.setList(list); 18 return page; 19 }
4、Dao層:
1)訪問數據庫,查詢數據庫中總記錄數
2)訪問數據庫,通過limit index,number 實現分頁查詢,得到請求頁的數據列表

1 public int getRecordsCount() { 2 conn=JDBCUtils.getConnection(); 3 String sql="select count(*) as totalPage from book"; 4 PreparedStatement ps=null; 5 ResultSet rs=null; 6 int totalPage=0; 7 8 try { 9 ps=conn.prepareStatement(sql); 10 rs=ps.executeQuery(); 11 if(rs.next()){ 12 totalPage=rs.getInt("totalPage"); 13 } 14 }catch(SQLException e){ 15 e.printStackTrace(); 16 } finally { 17 JDBCUtils.closeStatement(rs, ps); 18 JDBCUtils.closeConnection(conn); 19 } 20 return totalPage; 21 }

1 public List<Book> getPageList(int index, int pageSize) { 2 conn=JDBCUtils.getConnection(); 3 String sql="select id,book_name,author,price,sales,stock,img_path,create_date,update_date,status" 4 + " from book limit ?,?"; 5 PreparedStatement ps=null; 6 ResultSet rs=null; 7 List<Book> list=new ArrayList<Book>(); 8 9 try { 10 ps=conn.prepareStatement(sql); 11 ps.setInt(1, index); 12 ps.setInt(2, pageSize); 13 rs=ps.executeQuery(); 14 while (rs.next()) { 15 list.add(createBook(rs)); 16 } 17 }catch(SQLException e){ 18 e.printStackTrace(); 19 }finally { 20 JDBCUtils.closeStatement(rs, ps); 21 JDBCUtils.closeConnection(conn); 22 } 23 return list; 24 }
三、前台分頁的實現
為了實現分頁的通用性,我們在這里將分頁的代碼封裝到一個新的jsp頁面中
只需要在其他的jsp頁面中通過<%@include file="XXX"%>標簽導入,就可以實現分頁功能
注意:
1、jsp頁面中所有請求servlet的路徑都通過${page.path}&pageNumber=XXX的形式(page.path由請求動態獲取路徑信息,具有通用性)pageNumber表示請求頁碼
2、第一頁不能再向上一頁跳轉、末頁不能再想下一頁跳轉問題:通過在Page類的getPageNumber方法中限制頁碼的范圍實現
3、通過<c:set></c:set>設置頁碼在頁面中出現的范圍
1.總頁碼<=5時,顯示所有頁數
2.總頁碼>5時:
當前頁碼<=3時:顯示1~5頁
當前頁碼>3時:顯示當前頁在中間的5頁
4、通過<c:forEach></c:forEach>顯示由begin到end的5個頁面,當前頁用【】標識
1 <div class="page">
2 <a href="${page.path}&pageNumber=1">首頁</a>
3 <a href="${page.path}&pageNumber=${page.pageNumber-1}">上一頁</a>
4 <!--
5 始終保證當前頁在中間,一共顯示5頁 6 1.總頁碼<=5時,顯示所有頁數 7 2.總頁碼>5時: 8 當前頁碼<=3時:顯示1~5頁 9 當前頁碼>3時:顯示當前頁在中間的5頁,當當前頁為倒數前3頁時,顯示最后5頁 10 -->
11 <c:choose>
12 <c:when test="${page.totalPage<=5}">
13 <c:set var="begin" value="1"></c:set>
14 <c:set var="end" value="${page.totalPage}"></c:set>
15 </c:when>
16 <c:when test="${page.pageNumber<=3}">
17 <c:set var="begin" value="1"></c:set>
18 <c:set var="end" value="5"></c:set>
19 </c:when>
20 <c:when test="${page.pageNumber>3}">
21 <c:set var="begin" value="${page.pageNumber-2}"></c:set>
22 <c:set var="end" value="${page.pageNumber+2}"></c:set>
23 <c:if test="${page.pageNumber+2>=page.totalPage}">
24 <c:set var="begin" value="${page.totalPage-4}"></c:set>
25 <c:set var="end" value="${page.totalPage}"></c:set>
26 </c:if>
27 </c:when>
28 </c:choose>
29 <!-- 通過循環顯示由begin到end的5個頁面,當前頁用【】標識 -->
30 <c:forEach begin="${begin}" end="${end}" var="index">
31 <c:if test="${page.pageNumber==index}">
32 <a href="${page.path}&pageNumber=${index}">【${index}】</a>
33 </c:if>
34 <c:if test="${page.pageNumber!=index}">
35 <a href="${page.path}&pageNumber=${index}">${index}</a>
36 </c:if>
37 </c:forEach>
38
39 <a href="${page.path}&pageNumber=${page.pageNumber+1}">下一頁</a>
40 第${page.pageNumber}頁,共${page.totalPage}頁 41 轉到第<input id="setPage" type="text" value="${page.pageNumber}"/>頁,<a id="goto" href="">跳轉</a>
42 <a href="${page.path}&pageNumber=${page.totalPage}">末頁</a>
43 <script type="text/javascript">
44 window.onload=function(){ 45 var agoto=document.getElementById("goto"); 46 agoto.onclick=function(){ 47 var setPage=document.getElementById("setPage").value; 48 window.location="${page.path}&pageNumber="+setPage; 49 return false; 50 }; 51 }; 52 </script>
53 <!--或 <script type="text/javascript"> 54 $(function(){ 55 $("#goto").click(function(){ 56 var $setPage=$("#setPage").val(); 57 window.location="/MyBookStore/book?method=getPage&pageNumber="+$setPage; 58 return false; 59 }); 60 }); 61 </script> -->
62 </div>