🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 分页 ## 步骤 1 : 先运行,看到效果,再学习 先将完整的项目(向老师要相关资料),配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。 ## 步骤 2 : 模仿和排错 在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。 模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较**正确答案** ( 可运行项目 ) 和自己的代码,来定位问题所在。 采用这种方式,**学习有效果,排错有效率**,可以较为明显地提升学习速度,跨过学习路上的各个槛。 ## 步骤 3 : 基于前面的知识点 本知识点基于SSM整合进行 ## 步骤 4 : 本知识点效果 访问页面看到如图所示效果 `http://127.0.0.1:8080/ssm/listCategory` ![](https://box.kancloud.cn/c1291ffeba648ffa5cf55216204aac2b_620x316.png) ## 步骤 5 : 分页类:Page Page类用于存放分页信息: start: 开始位置 count: 每页的个数 last: 最后一页的位置 caculateLast()方法: 通过总数total和每页的个数计算出最后一页的位置 ~~~ package com.dodoke.util; public class Page { private int start = 0; private int count = 5; private int last = 0; public int getStart() { return start; } public void setStart(int start) { this.start = start; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public int getLast() { return last; } public void setLast(int last) { this.last = last; } public void calculateLast(int total) { // 假设总数是50,是能够被5整除的,那么最后一页的开始就是45 if (0 == total % count) { last = total - count; } // 假设总数是51,不能够被5整除的,那么最后一页的开始就是50 else { last = total - total % count; } } } ~~~ ## 步骤 6 : Category.xml 修改list,根据当有分页信息的时候,进行分页查询 增加total sql语句 ~~~ <?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.dodoke.mapper.CategoryMapper"> <insert id="add" parameterType="Category"> insert into category(name) values(#{name}) </insert> <delete id="delete" parameterType="Category"> delete from category where id=#{id} </delete> <update id="update" parameterType="Category"> update category set name=#{name} where id=#{id} </update> <select id="get" parameterType="int" resultType="Category"> select * from category where id=#{id} </select> <select id="list" resultType="Category"> select * from category <if test="start!=null and count!=null"> limit #{start},#{count} </if> </select> <select id="total" resultType="int"> select count(*) from category </select> </mapper> ~~~ ## 步骤 7 : CategoryMapper 增加total方法用于调用Category.xml 中total对应的sql语句 增加 list(Page page),根据分页来查询数据 ~~~ package com.dodoke.mapper; import java.util.List; import com.dodoke.pojo.Category; import com.dodoke.util.Page; public interface CategoryMapper { public int add(Category category); public void delete(int id); public int update(Category category); public Category get(int id); public List<Category> list(); public List<Category> list(Page page); public int total(); } ~~~ ## 步骤 8 : CategoryService 增加total用于获取所有 增加 list(Page page),根据分页来查询数据 ~~~ package com.dodoke.service; import java.util.List; import com.dodoke.pojo.Category; import com.dodoke.util.Page; public interface CategoryService { List<Category> list(); int total(); List<Category> list(Page page); } ~~~ ## 步骤 9 : CategoryServiceImpl 实现total()和list(Page page) 方法 ~~~ package com.dodoke.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.dodoke.mapper.CategoryMapper; import com.dodoke.pojo.Category; import com.dodoke.service.CategoryService; import com.dodoke.util.Page; @Service public class CategoryServiceImpl implements CategoryService { @Autowired CategoryMapper categoryMapper; @Override public List<Category> list() { // TODO Auto-generated method stub return categoryMapper.list(); } @Override public int total() { return categoryMapper.total(); } @Override public List<Category> list(Page page) { return categoryMapper.list(page); } } ~~~ ## 步骤 10 : CategoryController 1. 修改listCategory,接受分页信息的注入 ` listCategory(Page page)` 2. 根据分页对象,进行查询获取对象集合cs `List<Category> cs= categoryService.list(page);` 3. 根据总数,计算出最后一页的信息 `int total = categoryService.total();` ~~~ package com.dodoke.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.dodoke.pojo.Category; import com.dodoke.service.CategoryService; import com.dodoke.util.Page; //告诉spring mvc这是一个控制器类 @Controller @RequestMapping("") public class CategoryController { @Autowired CategoryService categoryService; @RequestMapping("listCategory") public ModelAndView listCategory(Page page) { int total = categoryService.total(); page.calculateLast(total); // 边界条件判断 // 首页,点击上一页,页面没有负数 int start = page.getStart(); if (start < 0) { page.setStart(0); } // 末页,点击下一页,开始页面不能超过最后一页 if (start > page.getLast()) { page.setStart(page.getLast()); } ModelAndView mav = new ModelAndView(); List<Category> cs = categoryService.list(page); // 放入转发参数 mav.addObject("cs",cs); // 放入jsp路径 mav.setViewName("listCategory"); return mav; } } ~~~ ## 步骤 11 : listCategory.jsp 修改listCategory.jsp,分别提供首页,上一页,下一页,末页等连接 ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <table border='1' cellspacing='0'> <tr> <td>id</td> <td>name</td> </tr> <c:forEach items="${cs}" var="c" varStatus="st"> <tr> <td>${c.id}</td> <td>${c.name}</td> </tr> </c:forEach> </table> <div style=""> <a href="?start=0">首 页</a> <a href="?start=${page.start - page.count }">上一页</a> <a href="?start=${page.start + page.count }">下一页</a> <a href="?start=${page.last }">末 页</a> </div> </body> </html> ~~~ ## 步骤 12 : 增加100个对象,用于测试 修改MybatisTest 类,新增100个对象,用于分页测试 ~~~ package com.dodoke.test; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.dodoke.mapper.CategoryMapper; import com.dodoke.pojo.Category; import com.dodoke.util.Page; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class MybatisTest { @Autowired private CategoryMapper categoryMapper; @Test public void testAdd() { for (int i = 0; i < 100; i++) { Category category = new Category(); category.setName("new Category"); categoryMapper.add(category); } } @Test public void testTotal() { int total = categoryMapper.total(); System.out.println(total); } @Test public void testList() { Page p = new Page(); p.setStart(2); p.setLast(3); List<Category> cs = categoryMapper.list(p); for (Category c : cs) { System.out.println(c.getName()); } } } ~~~ ## 步骤 13 : 测试 访问页面看到如图所示效果 `http://127.0.0.1:8080/ssm/listCategory` ![](https://box.kancloud.cn/c1291ffeba648ffa5cf55216204aac2b_620x316.png) ## 常见问题 1. 为什么在Controller类里没有把page放入mav里,jsp里也能用到呢? > 这句mav.addObject("page", page);框架已经省略了,可写可不写的,作为参数会被自动放进去的. 2. 我看到URL在点击链接之后变了,这里是提交了start么,提交了之后又是怎么把它赋给page对象的呢(像表单提交一样) ~~~ <a href="?start=${page.start-page.count}">上一页</a> ~~~ >是的,就是因为提交了start参数。 springmvc框架会自动把start参数注入到Page对象的start属性上。 ## 补充说明 > 分页界限判断,还可以使用JSTL中的if标签进行判断,提供个思路 > ~~~ <div style=""> <a href="?start=0">首 页</a> <c:if test="${page.start-page.count>=0}"> <a href="?start=${page.start-page.count}">上一页</a> </c:if> <c:if test="${page.start-page.count<0}"> <a href="javascript:void(0)">上一页</a> </c:if> <c:if test="${page.start+page.count<=page.last}"> <a href="?start=${page.start+page.count}">下一页</a> </c:if> <c:if test="${page.start+page.count>page.last}"> <a href="javascript:void(0)">下一页</a> </c:if> <a href="?start=${page.last}">末页</a> </div> ~~~