1. 程式人生 > >MyBatis學習——第五篇(手動分頁和pagehelper分頁實現)

MyBatis學習——第五篇(手動分頁和pagehelper分頁實現)

1:專案場景介紹

在專案中分頁是十分常見的功能,一般使用外掛實現分頁功能,但是在使用外掛之前我們首先手動寫出分頁程式碼,發然對比外掛實現的分頁,利於我們理解分頁底層實現和更好的實現外掛分頁實用技術,本次使用的外掛是PageHelper(採用都是物理分頁)

在開始之前我們建立兩個表,分別是t_user和person表,並且插入大量的資料。

t_user建表語句:

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

person建表語句:

CREATE TABLE `person` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `gender` varchar(255) DEFAULT NULL,
  `dept_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

 

2:手動分頁查詢針對user表資料

 專案首頁:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  <body>
	<h1>index.jsp</h1>
    
    <jsp:forward page="/servlet/UserServlet2">
    	<jsp:param value="all" name="method"/>
    </jsp:forward>
    
  </body>
</html>

首先開始我們的手動分頁,核心是一個分頁page類,裡面有用於分頁的各種屬性

package com.thit.util;

import java.util.List;

/**
 * 抽象出來的分頁類
 */
public class PageUtil {
	
	private int currentPageNum; //當前要看哪一頁,當前頁
	
	private int pageSize=10;//每頁顯示的條數,頁面顯示資料條數
	
	private int totalSize;//總記錄條數,總行數
	
	private int startIndex;//查詢開始記錄的索引 limit ? ? 開始索引
	
	private int totalPageNum;//總頁數
	
	private int prePageNum;//上一頁
	
	private int nextPageNum;//下一頁
	
	private List  records;//當前頁的記錄集
	
	
	//用於顯示頁面上的導航的頁號  使用者可自定義
	//開始頁碼
	private int startPageNum;
	//結束頁碼
	private int endPageNum;
	
	private String url;

	//使用構造方法,傳遞必要的兩個引數.第一個是頁碼,第二個總記錄條數
	public PageUtil(int currentPageNum,int totalrecords)
	{
		this.currentPageNum=currentPageNum;
		this.totalSize=totalrecords;
		//計算開始記錄索引
		this.startIndex=(currentPageNum-1)*pageSize;
		//計算總頁數
		this.totalPageNum=totalSize%pageSize==0?totalSize/pageSize:totalSize/pageSize+1;
		
		
		this.prePageNum=getPrePageNum1();
		
		this.nextPageNum=getNextPageNum1();
		//計算開始和結束頁號  這個根據自身可設計
		if(totalPageNum>9)
		{	
			//如果總頁數大於9 開始頁面
			startPageNum=currentPageNum-4;
			//結束頁面
			endPageNum=currentPageNum+4;

			if(startPageNum<1)
			{
				startPageNum=1;
				endPageNum=startPageNum+8;
			}
			if(endPageNum>totalPageNum)
			{
				endPageNum=totalPageNum;
				startPageNum=endPageNum-8;
			}
			
		}
		else
		{
			startPageNum=1;
			endPageNum=totalPageNum;

		}
		

	}
	public int getStartPageNum() {
		return startPageNum;
	}

	public void setStartPageNum(int startPageNum) {
		this.startPageNum = startPageNum;
	}
	public int getEndPageNum() {
		return endPageNum;
	}
	public void setEndPageNum(int endPageNum) {
		this.endPageNum = endPageNum;
	}
	//得到上一頁方法
	public int getPrePageNum1() {
		System.out.println("得到上一頁方法");
		//上一頁等於當前頁減1
		prePageNum=currentPageNum-1;
		//如過上一個小於0
		if(prePageNum<=0)
		{	//上一頁等於1
			System.out.println("上一頁小於0");
			prePageNum=1;
		}
		return prePageNum;
	}
	//得到下一頁方法
	public int getNextPageNum1() {
		//下一頁等於當前頁加1
		System.out.println("得到下一頁的方法");
		nextPageNum=currentPageNum+1;
		//如果下一頁大於總頁數
		if(nextPageNum>totalPageNum)
		{	//下一頁等於總頁數
			System.out.println("下一頁大於總頁數");
			nextPageNum=totalPageNum;
		}
		return nextPageNum;
	}

	public int getPrePageNum() {
		return prePageNum;
	}
	public int getNextPageNum() {
		return nextPageNum;
	}

	public int getCurrentPageNum() {
		return currentPageNum;
	}

	public void setCurrentPageNum(int currentPageNum) {
		this.currentPageNum = currentPageNum;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getTotalSize() {
		return totalSize;
	}

	public void setTotalSize(int totalSize) {
		this.totalSize = totalSize;
	}

	public int getStartIndex() {
		return startIndex;
	}

	public void setStartIndex(int startIndex) {
		this.startIndex = startIndex;
	}

	public int getTotalPageNum() {
		return totalPageNum;
	}

	public void setTotalPageNum(int totalPageNum) {
		this.totalPageNum = totalPageNum;
	}

	public List  getRecords() {
		return records;
	}

	public void setRecords(List  records) {
		this.records = records;
	}

	public void setPrePageNum(int prePageNum) {
		this.prePageNum = prePageNum;
	}

	public void setNextPageNum(int nextPageNum) {
		this.nextPageNum = nextPageNum;
	}


	public String getUrl() {
		return url;
	}


	public void setUrl(String url) {
		this.url = url;
	}

	@Override
	public String toString() {
		return "PageUtil [currentPageNum=" + currentPageNum + ", pageSize=" + pageSize + ", totalSize=" + totalSize
				+ ", startIndex=" + startIndex + ", totalPageNum=" + totalPageNum + ", 上一頁=" + prePageNum
				+ ", 下一頁=" + nextPageNum + ", records=" + records + ", startPageNum=" + startPageNum
				+ ", endPageNum=" + endPageNum + ", url=" + url + "]";
	}

}

然後是Servlet:

package com.thit.web;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.thit.service.Userservice;
import com.thit.serviceimpl.UserserviceImpl;
import com.thit.util.PageUtil;

@WebServlet("/servlet/UserServlet")
public class UserServlet  extends HttpServlet{
	Userservice userservice=new UserserviceImpl();
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("首先進入doget");
		String para=req.getParameter("method");
		System.out.println("方法引數:"+para);
		if(para.equals("all")) {
			//查詢所有使用者資訊
			 selectAllUsers(req,resp);
		}
		
	}
	
	private void selectAllUsers(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String num=req.getParameter("num");
		//第一次傳遞 num為空
		System.out.println("num的值是:"+num);
		if(null==num) {
			num="1";
		}
		PageUtil page=userservice.getAllusers(num);
		System.out.println(page.toString());
		req.setAttribute("page",page);
		//轉發到新的頁面
		req.getRequestDispatcher("/users.jsp").forward(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("首先進入doPost");
		this.doGet(req, resp);
	}
	

}

接著是service介面和實現類:

package com.thit.service;

import java.util.List;

import com.thit.entity.Person;
import com.thit.util.PageUtil;

public interface Userservice {
//查詢user
	public PageUtil getAllusers(String num);
//查詢person
	public List<Person> getAllperson();
}


-------------------實現類-----------------
package com.thit.serviceimpl;

import java.util.List;

import org.apache.commons.dbutils.DbUtils;

import com.thit.dao.Userdao;
import com.thit.daoimpl.Userdaoimpl;
import com.thit.entity.Person;
import com.thit.entity.User;
import com.thit.service.Userservice;
import com.thit.util.PageUtil;

public class UserserviceImpl implements Userservice {
	Userdao dao=new Userdaoimpl();
	
	public PageUtil getAllusers(String num) {
		// TODO Auto-generated method stub
		int currentPageNum=1;
		//如果當前頁不為空,當前頁等於num
		if(num!=null&&!num.trim().equals("")) {
			currentPageNum=Integer.parseInt(num);
			
		}
		//查詢總行數方法
		int totalPageNum=dao.getTotalSize();
		System.out.println("查詢總行數:"+totalPageNum);
		//當前頁 和 總行數
		PageUtil pageUtil=new PageUtil(currentPageNum, totalPageNum);
		//根據開始下標和行數查詢出來每頁的資料
		List<User> list=dao.getAllusers(pageUtil.getStartIndex(), pageUtil.getPageSize());
		for(User u:list) {
			System.out.println(u);
		}
		pageUtil.setRecords(list);
		
		return pageUtil;
	}

	public List<Person> getAllperson() {
		List<Person> lists=dao.getAllperson();
		return lists;
	}

}

dao層和實現類:

package com.thit.dao;

import java.util.List;

import com.thit.entity.Person;
import com.thit.entity.User;

public interface Userdao {
	//手寫分頁查詢user資料
	List<User> getAllusers(int startIndex,int pagesize) ; //開始索引和頁面條數
	//查詢表資料條數
	int getTotalSize();
	//pagehelper查詢所有person資料
	List<Person> getAllperson();
}

-----------------------dao實現類------------------------
package com.thit.daoimpl;

public class Userdaoimpl extends BaseDao implements Userdao {
	Dbtools dbtools=new Dbtools();
    //手寫查詢分頁
	public List<User> getAllusers(int startIndex, int pagesize) {
		// TODO Auto-generated method stub
		String sql = "select  * from t_user limit ?,?";
		List<User> lists = new ArrayList<User>();
		try {
            //通過工具類jdbc連線資料庫
			Connection connection = getConnection();
			PreparedStatement pStatement = connection.prepareStatement(sql);
			pStatement.setInt(1, startIndex);
			pStatement.setInt(2, pagesize);
			ResultSet re = pStatement.executeQuery();
			while (re.next()) {
				int id = re.getInt("id");
				String username = re.getString("username");
				String password = re.getString("password");
				String address = re.getString("address");

				User user = new User(id, username, address);
				lists.add(user);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return lists;
	}

	// 查詢總記錄數
	public int getTotalSize() {
		// TODO Auto-generated method stub
		int count=0;
		try {
			String sql = "select count(*) as num from t_user";
			Connection connection = getConnection();
			PreparedStatement pStatement = connection.prepareStatement(sql);

			ResultSet re = pStatement.executeQuery();
			
			while (re.next()) {
				count= re.getInt("num");
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return count;
	}
    
	    //pagehelper分頁
	public List<Person> getAllperson() {
		// mybatis查詢
		SqlSession sqlsession = dbtools.getSession();
		PersonMapper personMapper=sqlsession.getMapper(PersonMapper.class);
		List<Person> lists=personMapper.getAllPersons();
		return lists;
	}

}

最後的頁面展示程式碼jsp如下:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
	System.out.println("path:"+path);
	System.out.println("basePath:"+basePath);
	%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'users.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>

<body>
	<h1>分頁展示資料</h1>
	<table align="center" width="80%" border="1">
		<tr>
			<td>id</td>
			<td>username</td>
			<td>address</td>
		</tr>
		<!--在請求域中 是EL表示式中的一個隱含物件,類似request,如:${requestScope.username} 表示在request域中取得username屬性所對應的值,相當於request.getAttribute(“username”)。 -->

		<c:forEach items="${requestScope.page.records}" var="user">

			<tr>
				<td>${user.id}</td>
				<td>${user.username}</td>
				<td>${user.address}</td>
			</tr>
			<br>

		</c:forEach>
	</table>




	<div align="center">
	<%-- <%=request.getAttribute(“userlist”) %> 等價於$ { requestScope.userlist } --%>
	
			使用者表共${requestScope.page.totalSize}條資料
			<br>
			使用者表共${requestScope.page.totalPageNum}頁
			<br>
			<a href="<%= basePath%>servlet/UserServlet?method=all&num=2">第二頁</a>
			<br>
			
		<a href="${pageContext.request.contextPath}/servlet/UserServlet?method=all&num=1">首頁</a>
		
		<a href="${pageContext.request.contextPath}/servlet/UserServlet?method=all&num=${requestScope.page.prePageNum}">上一頁</a>
		<c:forEach begin="${requestScope.page.startPageNum}"
			end="${requestScope.page.endPageNum}" var="num">
			<a href="${pageContext.request.contextPath}/servlet/UserServlet?method=all&num=${num}">${num}</a>

		</c:forEach>

		<a href="${pageContext.request.contextPath}/servlet/UserServlet?method=all&num=${requestScope.page.nextPageNum}">下一頁</a>
		<a href="${pageContext.request.contextPath}/servlet/UserServlet?method=all&num=${requestScope.page.totalPageNum}">末頁</a>


		跳轉到 <input id="number" type="text" name="hello" size="6">頁<input
			type="button" value="跳轉" onclick="changeNumber()"></input>
			
			<br>
		<c:forEach begin="6"
			end="9" var="num">
			<a href="">${num}</a>
		</c:forEach>

		<script>
			function changeNumber() {
				//得到頁碼的具體值
				var num = document.getElementById("number").value;
				//是否是數字  輸入的數字一定是整數或者是小於總頁數的值
				window.location.href = "${pageContext.request.contextPath}/servlet/UserServlet?method=all&num="
						+ num;
			}
		</script>
	</div>
</body>
</html>

手動分頁結果顯示如下:

 3:pegeHelper外掛分頁針對user表資料

pegeHelper外掛分頁只是幾個部分

第一:需要的mybatis的配置檔案中配置外掛

第二:在servlect中使用PageHelper的startPage方法

第三:PageHelper攔截器會攔截查詢方法,並且在查詢的sql中根據不同的資料庫拼接分頁語句實現分頁

第四:將PageInfo這個類存放分頁的各種屬性資訊,核心程式碼就這三行,num的值由頁面傳遞過來

         Page<Object> page=PageHelper.startPage(Integer.valueOf(num), 10);
         List<Person> persons=userservice.getAllperson();
         PageInfo<?> pageHepler=page.toPageInfo();

需要新增mybatis配置檔案和mapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration 
PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

<!-- 
    plugins在配置檔案中的位置必須符合要求,否則會報錯,順序如下:
    properties?, settings?, 
    typeAliases?, typeHandlers?, 
    objectFactory?,objectWrapperFactory?, 
    plugins?, 
    environments?, databaseIdProvider?, mappers?
-->


<properties resource="db.properties"></properties>
	
	<typeAliases>
		<package name="com.thit.entity"/>
	</typeAliases>
	
	<!--配置外掛  -->
	
	<plugins>
		    <!-- com.github.pagehelper為PageHelper類所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置引數,後面會有所有的引數介紹 -->
        <property name="param1" value="value1"/>
	</plugin>
	
	</plugins>
	
	


<environments default="demo">

	<environment id="demo">
	  	<!-- type="JDBC" 代表使用JDBC的提交和回滾來管理事務 -->
		<transactionManager type="JDBC"></transactionManager>
	 	    <!-- mybatis提供了3種資料來源型別,分別是:POOLED,UNPOOLED,JNDI -->
            <!-- POOLED 表示支援JDBC資料來源連線池 -->
            <!-- UNPOOLED 表示不支援資料來源連線池 -->
            <!-- JNDI 表示支援外部資料來源連線池 -->
		
		<dataSource type="POOLED">
	        <property name="driver" value="${mysqldriver}"/>
	        <property name="url" value="${mysqlurl}"/>
	        <property name="username" value="${mysqlusername}"/>
	        <property name="password" value="${mysqlpassword}"/>
		</dataSource>
	</environment>
</environments>

	 <mappers>
	 		<!-- <mapper resource="mapper/userMapper.xml"/> -->
	 	<mapper resource="mapper/PersonMapper.xml"></mapper> 
	 		<!-- 	<mapper class="com.thit.dao.PersonMapper"/> -->
	 </mappers>
 </configuration>


---------------------下邊的為PersonMapper配置檔案-----------------
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.thit.dao.PersonMapper">

	 
	<select id="getAllPersons" resultType="Person">
		select * from person
	</select>
	
</mapper>


然後servlet如下:

package com.thit.web;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.thit.entity.Person;
import com.thit.service.Userservice;
import com.thit.serviceimpl.UserserviceImpl;
import com.thit.util.PageUtil;

@WebServlet("/servlet/UserServlet2")
public class UserServlet2  extends HttpServlet{
	Userservice userservice=new UserserviceImpl();
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("首先進入doget");
		String para=req.getParameter("method");
		System.out.println("方法引數:"+para);
		if(para.equals("all")) {
			//查詢所有使用者資訊
			 selectAllUsers(req,resp);
		}
		
	}
	
	private void selectAllUsers(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String num=req.getParameter("num");
		//第一次傳遞num為頁數  num為空
		System.out.println("num的值是:"+num);
		if(null==num) {
			num="1";
		}
		
		//第二種,Mapper介面方式的呼叫,頁數和頁面顯示條數
		 Page<Object> page=PageHelper.startPage(Integer.valueOf(num), 10);
		 
		 List<Person> persons=userservice.getAllperson();
		 PageInfo<?> pageHepler=page.toPageInfo();
		 
		 req.setAttribute("persons", persons);
		 req.setAttribute("pagehelper", pageHepler);
		
		//轉發到新的頁面
		req.getRequestDispatcher("/persons.jsp").forward(req, resp);
		
		
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("首先進入doPost");
		this.doGet(req, resp);
	}
	

}

service和dao層在上邊的程式碼中已經貼出來了。

頁面展示程式碼如下:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'users.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>

    <table align="center" width="80%" border="1">
      <tr><td>id</td><td>username</td><td>address</td></tr>

      <c:forEach items="${requestScope.persons}" var="person">

          <tr><td>${person.id} </td><td>${person.username}</td><td>${person.email}</td></tr><br>

      </c:forEach>
    </table>




    <div align="center">

    共${requestScope.pagehelper.total}條/共${requestScope.pagehelper.pages}頁FirstPage
  <a href="${pageContext.request.contextPath}/servlet/UserServlet2?method=all&num=1">首頁</a>

  <a href="${pageContext.request.contextPath}/servlet/UserServlet2?method=all&num=${requestScope.pagehelper.prePage}">上一頁</a>
  <c:forEach   items="${requestScope.pagehelper.navigatepageNums}" var="num">
   <a href="${pageContext.request.contextPath}/servlet/UserServlet2?method=all&num=${num}">${num}</a>
  
  </c:forEach>
  
  <a href="${pageContext.request.contextPath}/servlet/UserServlet2?method=all&num=${requestScope.pagehelper.nextPage}">下一頁</a>
  <a href="${pageContext.request.contextPath}/servlet/UserServlet2?method=all&num=${requestScope.pagehelper.pages}">末頁</a>
  
  
  跳轉到
  <input id="number" type="text" name="hello" size="6">頁<input type="button" value="跳轉" onclick="changeNumber()"></input>
  
  <script>
    function changeNumber()
    {
       var num=document.getElementById("number").value;
       //是否是數字  輸入的數字一定是整數或者是小於總頁數的值
      window.location.href="${pageContext.request.contextPath}/servlet/UserServlet2?method=all&num="+num;
    }

  </script>

    </div>
  </body>
</html>

最後的展示效果如下: