網頁的分頁功能的實現比較簡單,實現方法也多種多樣。
今天總結一個簡單的Jsp真分頁實例。
首先,提到分頁就要先明確一個概念,何為真分頁何謂假分頁。
假分頁:一次性從數據庫讀出表的所有數據一次性的返回給客戶端,由js來控制每一頁的顯示。
真分頁:由程序控制,每一次只返回一頁大小的數據,顯示到客戶端。
由此可以很清楚的分辨出真假分頁各自的優缺點:
假分頁:由于一次性讀出所有數據并返回給客戶端,如果數據量龐大,所以這一次的動作可能是非常消耗服務器資源和帶寬的,
但是返回給客戶端以后就非常輕松了,客戶在一段時間內不會再像服務器端請求資源。但不代表可能出現一些意外情況,
比如說客戶將瀏覽器關閉,重新訪問網站等。所以,如果數據量相當龐大,不建議使用用真分頁。
真分頁:假分頁每次只取需要的數據返回給客戶端,比起真分頁沒有那么大的數據庫壓力。但也因為這個工作特性,所以假分頁
的方法需要頻繁和服務器端進行交互。既然頻繁交互,自然也會給服務器帶來負擔。
綜上:如果數據量較小,使用假分頁的效果會更優,如果數據量龐大,使用真分頁的效果更優。
分析完特性,下面就來列舉一個簡單的真分頁實例。
真分頁是通過程序來控制的,每次向數據庫請求需要的數據。
簡述實現思路業務流程:
首先:客戶端帶著page參數請求客戶端,若沒有帶page參數,說明是第一次訪問,則page參數默認為0;
其次:服務端根據page參數,調用相關函數,從數據庫中取出表中數據,封裝成相關對象,返回給客戶端,并且返回新page參數及總頁數;
最后:再客戶端顯示請求的相關數據,并根據page參數及總頁數兩個參數,決定上一頁下一頁的按鈕是否可用。
數據庫操作類:
public class DBBean { private Connection con; private PreparedStatement pstmt; private ResultSet rs; private String dbName ="test"; private String dbuser = "root"; private String dbpass ="******"; static{ try{ Class.forName("com.mysql.jdbc.Driver"); }catch(ClassNotFoundException e){ System.out.println(e); } } public void prepareConnection(){ try{ con=DriverManager.getConnection("jdbc:mysql://localhost:3306/"+dbName,dbuser,dbpass); }catch(SQLException e){ System.out.println(e); } } //關閉連接 public void close(){ try { if(con!=null) con.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } con = null; try { if(pstmt!=null) pstmt.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } pstmt = null; } //設置參數 private void setParems(String[] parems){ if(parems!=null){ for(int i=0;i<parems.length;i++){ try { pstmt.setString(i+1, parems[i]); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public ResultSet executeQuery(String sql,String[] parems){ ResultSet res = null; prepareConnection(); try { pstmt = con.prepareStatement(sql); setParems(parems); res = pstmt.executeQuery(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ } return res; }}
學生類:
public class StudentBean { private long id; private String name; private String phone; private int age; private int score; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getScore() { return score; } public void setScore(int score) { this.score = score; }}
學生數據操作類
public class StudentDao implements StudentDaoIn {@Override public ArrayList<StudentBean> findByPage(int page){ DBBean db = new DBBean(); int begin = (page-1) * 5; String sql = "select * from t_student limit "+begin+",5"; ResultSet rs = db.executeQuery(sql,null); ArrayList<StudentBean> list = new ArrayList<StudentBean>(); try { while(rs.next()){ StudentBean st = new StudentBean(); st.setName(rs.getString("name")); st.setAge(rs.getInt("age")); st.setId(rs.getInt("id")); st.setPhone(rs.getString("phnoe")); st.setScore(rs.getInt("score")); list.add(st); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return list; } @Override public int userCount(){ DBBean db = new DBBean(); String sql = "select count(*) from t_student"; ResultSet rs = db.executeQuery(sql, null); int count = 0; try { rs.next(); count = rs.getInt(1); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return count; }}
相關業務邏輯
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub String page = null; page = request.getParameter("page"); if(page == null || page=="") page = "1"; StudentDao studao = new StudentDao(); request.setAttribute("student",studao.findByPage(Integer.parseInt(page))); request.setAttribute("pagenum",studao.userCount()/5+1);//總頁數 request.setAttribute("page", page);//當前頁 request.getRequestDispatcher("student.jsp").forward(request, response); }
前臺JSP代碼:
<table id="t_stu" border="1" cellpadding="2" cellspacing="0"> <thead> <tr> <th>ID</th> <th>姓名</th> <th>年齡</th> <th>電話</th> <th>成績</th> </tr> </thead> <c:forEach items="${student}" var="st"> <tr> <td>${st.getId()}</td> <td>${st.getName()}</td> <td>${st.getAge()}</td> <td>${st.getPhone()}</td> <td>${st.getScore()}</td> </tr> </c:forEach></table><br>共 ${pagenum}頁 當前 第${page}頁 <c:choose> <c:when test="${page>1}"> <a href="getSutent?page=${page-1}" rel="external nofollow" ><input type="button" value="上一頁" ></a> </c:when> <c:otherwise> <input type="button" value="上一頁" disabled="disabled" /> </c:otherwise></c:choose><c:choose> <c:when test="${page!=pagenum}"> <a href="getSutent?page=${page+1}" rel="external nofollow" ><input type="button" value="下一頁"></a> </c:when> <c:otherwise> <input type="button" value="下一頁" disabled="disabled" /> </c:otherwise></c:choose>
本例是真分頁的一個簡單實現,有著明顯的缺點。
例如:
1.在后臺相關業務邏輯處,只對page做了簡單的判斷,因為查詢相關page時,參數是寫入前臺a標簽中的,所以懂技術的用戶,可以隨意改動其值
由此查詢數據庫可能帶來意想不到的錯誤。
2.功能不夠完善,僅提供了上一頁下一頁按鈕的簡單功能。
另外:實現假分頁時可以結合ajax和json。以此可實現無刷新翻頁,看起來功能和真分頁一樣。。。
新聞熱點
疑難解答