使用PageHelper定制软件实现分页查询(详细):
实现环境:
语言 | 编程工具 | 框架 | 分页插件 | 前端 | 定制软件前端数据获取 |
---|---|---|---|---|---|
Java | IDEA | SpringBoot | pageHelper | BootStrap | Thymeleaf |
**项目背景:**定制软件我们需要在mydb定制软件这个数据库的user定制软件表中查询并在 一个HTML定制软件页面中分页显示出表中的数据。
一、定制软件我们先实现显示出全部内容
定制软件我们先从头到尾的创建一个SpringBoto项目,定制软件然后再实现分页。
1、定制软件首先我们创建一个新的SpringBoot项目:
2、定制软件创建实体类User:
package com.example.pagehelper.pojo;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;//这里使用Lombok直接生成get和set定制软件方法以及构造函数@Data@AllArgsConstructor@NoArgsConstructorpublic class User { int id; String name; int age; String pwd;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
3、创建dao层 mapper接口:
package com.example.pagehelper.mapper;import com.example.pagehelper.pojo.User;import org.apache.ibatis.annotations.Mapper;import java.util.List;//定制软件使用注解将Mapper添加到IOC容器@Mapperpublic interface UserMapper { //定制软件通过注解查询出全部数据 @Select("select * from user") List<User> queryUser();}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
4、创建业务层接口userService:
package com.example.pagehelper.service;import com.example.pagehelper.pojo.User;import java.util.List;public interface userService { List<User> queryUser();}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
5、创建业务层实现类 userServiceImpl:
package com.example.pagehelper.service;import com.example.pagehelper.mapper.UserMapper;import com.example.pagehelper.pojo.User;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;@Service("userService")public class userServiceImpl implements userService{ @Autowired private UserMapper userMapper; @Override public List<User> queryUser() { return userMapper.queryUser(); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
6、创建userController类:
package com.example.pagehelper.controller;import com.example.pagehelper.pojo.User;import com.example.pagehelper.service.userServiceImpl;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import javax.annotation.Resource;import java.util.List;@Controllerpublic class userController { @Resource private userServiceImpl userService; @RequestMapping("/user") public String queryUser(Model model){ List<User> users = userService.queryUser(); model.addAttribute("user",users); return "allUser"; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
7、配置application.properties配置文件:
#JDBC连接信息配置spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8spring.datasource.username=rootspring.datasource.password=123456#设置为 true 来自动中断循环。spring.main.allow-circular-references=true#thymeleaf配置#前缀spring.thymeleaf.prefix=classpath:/templates/#后缀spring.thymeleaf.suffix=.html#表示前端页面文件为HTML5spring.thymeleaf.mode=HTML5#字符集编码为UTF-8spring.thymeleaf.encoding=UTF-8spring.thymeleaf.content-type=text/htmlspring.thymeleaf.cache=falsespring.thymeleaf.enabled=true
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
8、编写HTML页面代码:
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"><head> <title>用户列表</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 引入 Bootstrap --> <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"></head><body><div class="container"> <div class="row clearfix"> <div class="col-md-12 column"> <table class="table table-hover table-striped"> <thead> <tr> <th>用户ID</th> <th>用户名</th> <th>年龄</th> <th>密码</th> <th>操作</th> </tr> </thead> <tr th:each="user,iterStat : ${alluser}"> <td th:text="${user.id}"></td> <td th:text="${user.name}"></td> <td th:text="${user.age}"></td> <td th:text="${user.pwd}"></td> <td> <a th:href="#">更改</a> | <a th:href="#">删除</a> </td> </tr> </table> </div> </div></div>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
此时我们整个项目的全部显示就算是完成了(以上代码会出现一个问题,解决方法可见文末!!!)
到此我们的显示就没问题了,接下来我们再实现分页显示。
二、实现分页显示
这里我们通过 pagehelper 插件来实现分页显示:
官方使用文档:
1、导包:
我们要使用PageHelper插件的话,需要先在pom文件中导入相关的依赖包。
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.3</version></dependency>
- 1
- 2
- 3
- 4
- 5
2、配置application.properties:
#pagehelper配置pagehelper.helper-dialect=mysqlpagehelper.reasonable=truepagehelper.support-methods-arguments=truepagehelper.params=count=countSql
- 1
- 2
- 3
- 4
- 5
3、开始使用PageHelper:
这里官方给了几种不同的方法:
//第一种,RowBounds方式的调用List<User> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(0, 10));//第二种,Mapper接口方式的调用,推荐这种使用方式。PageHelper.startPage(1, 10);List<User> list = userMapper.selectIf(1);//第三种,Mapper接口方式的调用,推荐这种使用方式。PageHelper.offsetPage(1, 10);List<User> list = userMapper.selectIf(1);//第四种,参数方法调用//存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数public interface CountryMapper { List<User> selectByPageNumSize( @Param("user") User user, @Param("pageNum") int pageNum, @Param("pageSize") int pageSize);}//配置supportMethodsArguments=true//在代码中直接调用:List<User> list = userMapper.selectByPageNumSize(user, 1, 10);//第五种,参数对象//如果 pageNum 和 pageSize 存在于 User 对象中,只要参数有值,也会被分页//有如下 User 对象public class User { //其他fields //下面两个参数名和 params 配置的名字一致 private Integer pageNum; private Integer pageSize;}//存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数public interface CountryMapper { List<User> selectByPageNumSize(User user);}//当 user 中的 pageNum!= null && pageSize!= null 时,会自动分页List<User> list = userMapper.selectByPageNumSize(user);//第六种,ISelect 接口方式//jdk6,7用法,创建接口Page<User> page = PageHelper.startPage(1, 10).doSelectPage(new ISelect() { @Override public void doSelect() { userMapper.selectGroupBy(); }});//jdk8 lambda用法Page<User> page = PageHelper.startPage(1, 10).doSelectPage(()-> userMapper.selectGroupBy());//也可以直接返回PageInfo,注意doSelectPageInfo方法和doSelectPagepageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(new ISelect() { @Override public void doSelect() { userMapper.selectGroupBy(); }});//对应的lambda用法pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> userMapper.selectGroupBy());//count查询,返回一个查询语句的count数long total = PageHelper.count(new ISelect() { @Override public void doSelect() { userMapper.selectLike(user); }});//lambdatotal = PageHelper.count(()->userMapper.selectLike(user));
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
4、userServiceImpl类:
前面的User类,UserMapper以及userService都不需要更改,我们直接在userServiceImpl中添加分页查询的方法即可。
//分页查询功能 public List<User> queryUserByPage(Integer pageNum,Integer pageSize){ PageHelper.startPage(pageNum,pageSize); return userMapper.queryUser(); }
- 1
- 2
- 3
- 4
- 5
5、userController类:
添加一个控制器。
@RequestMapping("/allByPage") public String allBookByPage(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "5") Integer pageSize,//设置默认页面大小为5 Model model){ //为了程序的严谨性,判断非空: if(pageNum == null){//若pageNum为空 pageNum = 1; //设置默认当前页为1 } if(pageNum <= 0){ //若为负数 pageNum = 1; //设置默认值为1 } if(pageSize == null){ //若页面大小为空 pageSize = 5; //设置默认每页显示的数据数 } try { //调用分页查询的方法 List<User> users = userService.queryUserByPage(pageNum,pageSize); model.addAttribute("alluser",users);//查询出的数据传到前端 PageInfo pageInfo = new PageInfo(users,pageSize);//设置页面大小 model.addAttribute("pageInfo",pageInfo);//将页面信息传到前端 }finally { PageHelper.clearPage(); //清理 ThreadLocal 存储的分页参数,保证线程安全 } return "allUser"; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
6、HTML页面:
在table标签后面添加切换页面按钮。
<ul class="pagination justify-content-end" style="float: right"> <!--首页--> <li class="page-item"> <a class="page-link" th:href="'allByPage?pageNum='+${pageInfo.navigateFirstPage}">首页</a> </li> <!--上一页--> <li class="page-item"> <a class="page-link" th:href="'allByPage?pageNum='+${pageInfo.prePage}">上一页</a> </li> <!--循环遍历显示中间的页数--> <li th:each="list:${pageInfo.navigatepageNums}"> <a th:href="'allByPage?pageNum='+${list}" th:text="${list}" th:if="${list != pageInfo.pageNum}"></a> <span style="font-weight: bold;background: #6faed9;" th:if="${list == pageInfo.pageNum}" th:text="${list}" ></span> </li> <!--下一页--> <li class="page-item" th:if="${pageInfo.hasNextPage}"> <a class="page-link" th:href="'allByPage?pageNum='+${pageInfo.nextPage}">下一页</a> </li> <!--尾页--> <li class="page-item"><a class="page-link" th:href="'allByPage?pageNum='+${pageInfo.navigateLastPage}">尾页</a></li></ul>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
7、结果展示:
第一页:
第二页:
三、可能出现的问题:
2022-05-16 16:55:33.656 ERROR 10964 --- [nio-8080-exec-1] org.thymeleaf.TemplateEngine : [THYMELEAF][http-nio-8080-exec-1] Exception processing template "allUser": An error happened during template parsing (template: "class path resource [templates/allUser.html]")
- 1
如果出现找不到html资源的错误,可能是因为我们在使用 时出现错误,如获取controller传过来的数据时等等;此时我们应该仔细检查一下在使用 thymeleaf 的过程中是否有语法错误。
在上述代码中,我们就会出现一个这样的问题:
首先,此时我们可以先考虑是不是在controller查询的时候出了问题,我们可以在controller中输出一下我们查询出来的数据:
这里我们可以看到虽然报错了,但是数据是查出来了的。这时就可以确定问题肯定是在HTML代码中了。
然后我们查看HTML代码:
这里可以发现,我们在a标签中多写了两个 th: ,且后面没有去获取一个值;所以这里才会报错!
**总结:**遇到这种问题要么是controller中查询数据时出了问题使得HTML中获取不到;要么就是HTML中thymelefa语法有问题,只要仔细检查thymelefa语法即可。