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>

最后的展示效果如下:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值