目的:实现分页
效果:
实现步骤:
1.搭建mybatis
1.1导入jar包
mybatis-3.4.1.jar
mysql-connector-java-5.1.38.jar
(记得buildPath)
1.2连接数据库
资源文件下建两个配置文件
db.properties存放连接数据库的信息
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///student?characterEncoding=UTF-8&useSSL=true&serverTimezone=UTC
username=root
password=root
Mybatis-config.xml 为主配置文件
<?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>
<properties resource="db.properties"></properties>
<!-- <typeAliases>
<typeAlias alias="" type="" />
</typeAliases> -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<!-- 读取数据库连接的信息 -->
<dataSource type="POOLED">
<property name="driver" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<!-- 加载XXXMapper.xml配置文件 -->
<mappers>
<mapper resource="cn/wolfcode/mapper/StudentMapper.xml" />
</mappers>
</configuration>
写一个工具类用于获取数据库连接
/**
*
* @author 红烛
*
*/
public class MybatisUtil {
private static SqlSessionFactory factory;
private MybatisUtil(){};
static{
try {
factory=new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("Mybatis-config.xml"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSession(){
SqlSession session=factory.openSession();
return session;
}
}
2.封装sql查询所需的参数为对象
QueryObject类中存放了sql语句查询所需参数
private int currentPage=PageContant.CURRENT_PAGE;
@Getter
@Setter
public class QueryObject {
/**
* 默认初始页
*/
private int currentPage=1;
/**
* 每页显示的数据条数
*/
private int pageSize=3;
/**
*SQL语句中的参数是通过get方法拿到属性的,beginIndex表示当前页第一条数据的索引
**/
public int getBeginIndex(){
return (this.currentPage-1)*this.pageSize;
}
}
3封装分页相关参数
PageResult类中封装了分页的相关数据
@Getter
@Setter
public class PageResult {
private int currentPage=PageContant.CURRENT_PAGE;
private int pageSize=PageContant.PAGE_SIZE;
private int totalCount;
private int totalPage;
private int prevPage;
private int nextPage;
private List<Student> listDate;
/**
*少参构造器调多参构造器,当没有数据时只需要调这两个参数的构造器就可以没必要调4个参数的
*new ArrayList<Student>() 这样写是因为jsp页面使用<c:forEach>遍历的集合不能空,否则会报空指针异常
* 这样写可在没有数据时也不报异常
**/
public PageResult(int currentPage,int pageSize){
this(currentPage, pageSize, new ArrayList<Student>(), 0);
}
public PageResult(int currentPage, int pageSize, List<Student> listDate, int totalCount) {
/**
*当前页
**/
this.currentPage = currentPage;
/**
*每页显示的数据条数
**/
this.pageSize = pageSize;
/**
*当前页的数据集合
**/
this.listDate = listDate;
/**
*数据的总条数
**/
this.totalCount = totalCount;
/**
*总页数
**/
this.totalPage=this.totalCount % this.pageSize==0
?this.totalCount / this.pageSize
:this.totalCount / this.pageSize+1;
/**
*前一页
**/
this.prevPage=this.currentPage-1>1?this.currentPage-1:1;
/**
*下一页
**/
this.nextPage=this.currentPage+1<this.totalPage
?this.currentPage+1
:this.totalPage;
}
}
4.StudentMapper.xml
StudentMapper接口中什么都不用写,将方法写到dao层接口中,当然写没问题
<!-- 得到当前页结果集 -->
<select id="queryForList" resultType="cn.wolfcode.domain.Student">
select * from student
limit #{beginIndex},#{pageSize}
</select>
<!-- 得到数据总个数 -->
<select id="queryForCount" resultType="int">
select count(*) from student
</select>
5.dao层实现
IStudentDAO
/**
*
* @author 红烛
*
*/
public interface IStudentDAO {
/**
* 查询结果集
* @return
*/
List<Student> queryForList(QueryObject qo);
/**
* 查询数据数量
* @return
*/
int queryForCount(QueryObject qo);
}
StudentDAOImpl 接口实现
@Override
public List<Student> queryForList(QueryObject qo) {
SqlSession session=MybatisUtil.getSession();
List<Student> list=session.selectList("cn.wolfcode.mapper.StudentMapper.queryForList",qo);
session.commit();
session.close();
return list;
}
@Override
public int queryForCount(QueryObject qo) {
SqlSession session=MybatisUtil.getSession();
int totalCount=session.selectOne("cn.wolfcode.mapper.StudentMapper.queryForCount",qo);
session.commit();
session.close();
return totalCount;
}
6.service层实现
IStudentService 接口
/**
*
* @author 红烛
*
*/
public interface IStudentService {
/**
* 分页所有结果
* @param qo
* @return
*/
PageResult query(QueryObject qo);
}
IStudentService 接口实现
/**
*
* @author 红烛
*
*/
public class StudentServiceImpl implements IStudentService {
private IStudentDAO dao = new StudentDAOImpl();
@Override
public PageResult query(StudentQueryObject qo) {
int totalCount = dao.queryForCount(qo);
if (totalCount == 0) {
//如果没有数据调用两个参数的构造器
return new PageResult(qo.getCurrentPage(), qo.getPageSize());
}
List<Student> listDate = dao.queryForList(qo);
return new PageResult(qo.getCurrentPage(), qo.getPageSize(), listDate, totalCount);
}
}
7.servlet实现
/**
*
* @author 红烛
*
*/
@WebServlet("/student")
public class StudentServlet extends HttpServlet{
private IStudentService studentService=new StudentServiceImpl();
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
QueryObject qo=new QueryObject();
req2stu(request, qo);
PageResult result=studentService.query(qo);
request.setAttribute("result", result);
//跳转到主页·list.jsp
request.getRequestDispatcher("/WEB-INF/view/list.jsp").forward(request, response);
}
//接收jsp页面数据封装成对象
protected void req2stu(HttpServletRequest request, QueryObject qo) {
String currentPage=request.getParameter("currentPage");
String pageSize=request.getParameter("pageSize");
if(StringUtil.hasLength(currentPage)){
qo.setCurrentPage(Integer.valueOf(currentPage));
}
if(StringUtil.hasLength(pageSize)){
qo.setPageSize(Integer.valueOf(pageSize));
}
}
}
8.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>学生信息页</title>
<!--点击上一页下一页首页尾页时实现表单的提交,不然没有翻页效果-->
<script type="text/javascript">
funtion submitForm(pageNum){
document.getElementById("currentPage").value=pageNum;
//forms[0]表示提交的是本页面的第一个表单
document.forms[0].submit();
}
</script>
</head>
<body>
<div>
<table border="1" cellspacing="0" cellpadding="0">
<thead>
<tr>
<td>编号</td>
<td>姓名</td>
<td>年龄</td>
<td>生日</td>
<td>地址</td>
<td>电话</td>
<td>邮箱</td>
</tr>
</thead>
<tbody>
<c:forEach var="stu" items="${result.listDate}">
<tr>
<td>${stu.id}</td>
<td>${stu.name}</td>
<td>${stu.age}</td>
<!-- type="date"或是 type="both" 都可以实现日期格式化-->
<td><fmt:formatDate pattern="yyyy-MM-dd"
value="${stu.birthday}" type="date" /></td>
<td>${stu.address}</td>
<td>${stu.phone}</td>
<td>${stu.email}</td>
</tr>
</c:forEach>
</tbody>
<tfoot>
<tr>
<td colspan="8">
<a href="javaScript:submitForm(1)">首页</a>
<a href="javaScript:submitForm(${result.prevPage})">上一页</a>
<a href="javaScript:submitForm(${result.nextPage})">下一页</a>
<a href="javaScript:submitForm(${result.totalPage})">尾页</a>
共${result.totalCount}条数据
页码${result.currentPage}/${result.totalPage}页
每页显示
<select name="pageSize">
<option ${result.pageSize==3 ? 'selected' : ''}>3</option>
<option ${result.pageSize==5 ? 'selected' : ''}>5</option>
<option ${result.pageSize==7 ? 'selected' : ''}>7</option>
</select>
条数据
跳转至
<input type="text" name="currentPage" id="currentPage" value="${result.currentPage}"/>页
<input type="submit" value="GO"/>
</td>
</tr>
</tfoot>
</table>
</div>
</body>
</html>