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>
最後的展示效果如下: