实现环境:
语言
编程工具
分页插件
前端
前端数据获取
Java
IDEA
SpringBoot
pageHelper
**项目背景:**我们需要在mydb这个数据库的user表中查询并在 一个HTML页面中分页显示出表中的数据。
我们先从头到尾的创建一个SpringBoto项目,然后再实现分页。

package com.example.pagehelper.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//这里使用Lombok直接生成get和set方法以及构造函数
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
int id;
String name;
int age;
String pwd;
}
package com.example.pagehelper.mapper;
import com.example.pagehelper.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
//使用注解将Mapper添加到IOC容器
@Mapper
public interface UserMapper {
//通过注解查询出全部数据
@Select("select * from user")
List queryUser();
}
package com.example.pagehelper.service;
import com.example.pagehelper.pojo.User;
import java.util.List;
public interface userService {
List queryUser();
}
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 queryUser() {
return userMapper.queryUser();
}
}
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;
@Controller
public class userController {
@Resource
private userServiceImpl userService;
@RequestMapping("/user")
public String queryUser(Model model){
List users = userService.queryUser();
model.addAttribute("user",users);
return "allUser";
}
}
#JDBC连接信息配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
#设置为 true 来自动中断循环。
spring.main.allow-circular-references=true
#thymeleaf配置
#前缀
spring.thymeleaf.prefix=classpath:/templates/
#后缀
spring.thymeleaf.suffix=.html
#表示前端页面文件为HTML5
spring.thymeleaf.mode=HTML5
#字符集编码为UTF-8
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
spring.thymeleaf.enabled=true
用户列表
此时我们整个项目的全部显示就算是完成了(以上代码会出现一个问题,解决方法可见文末!!!)

到此我们的显示就没问题了,接下来我们再实现分页显示。
这里我们通过 pagehelper 插件来实现分页显示:
官方使用文档:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md
我们要使用PageHelper插件的话,需要先在pom文件中导入相关的依赖包。
com.github.pagehelper
pagehelper-spring-boot-starter
1.2.3
#pagehelper配置
pagehelper.helper-dialect=mysql
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
pagehelper.params=count=countSql
这里官方给了几种不同的方法:
//第一种,RowBounds方式的调用
List list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(0, 10));
//第二种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.startPage(1, 10);
List list = userMapper.selectIf(1);
//第三种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.offsetPage(1, 10);
List list = userMapper.selectIf(1);
//第四种,参数方法调用
//存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
public interface CountryMapper {
List selectByPageNumSize(
@Param("user") User user,
@Param("pageNum") int pageNum,
@Param("pageSize") int pageSize);
}
//配置supportMethodsArguments=true
//在代码中直接调用:
List 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 selectByPageNumSize(User user);
}
//当 user 中的 pageNum!= null && pageSize!= null 时,会自动分页
List list = userMapper.selectByPageNumSize(user);
//第六种,ISelect 接口方式
//jdk6,7用法,创建接口
Page page = PageHelper.startPage(1, 10).doSelectPage(new ISelect() {
@Override
public void doSelect() {
userMapper.selectGroupBy();
}
});
//jdk8 lambda用法
Page page = PageHelper.startPage(1, 10).doSelectPage(()-> userMapper.selectGroupBy());
//也可以直接返回PageInfo,注意doSelectPageInfo方法和doSelectPage
pageInfo = 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);
}
});
//lambda
total = PageHelper.count(()->userMapper.selectLike(user));
前面的User类,UserMapper以及userService都不需要更改,我们直接在userServiceImpl中添加分页查询的方法即可。
//分页查询功能
public List queryUserByPage(Integer pageNum,Integer pageSize){
PageHelper.startPage(pageNum,pageSize);
return userMapper.queryUser();
}
添加一个控制器。
@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 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";
}
在table标签后面添加切换页面按钮。
第一页:

第二页:

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]")
如果出现找不到html资源的错误,可能是因为我们在使用 thymeleaf 时出现错误,如获取controller传过来的数据时等等;此时我们应该仔细检查一下在使用 thymeleaf 的过程中是否有语法错误。
在上述代码中,我们就会出现一个这样的问题:
首先,此时我们可以先考虑是不是在controller查询的时候出了问题,我们可以在controller中输出一下我们查询出来的数据:

这里我们可以看到虽然报错了,但是数据是查出来了的。这时就可以确定问题肯定是在HTML代码中了。
然后我们查看HTML代码:

这里可以发现,我们在a标签中多写了两个 th: ,且后面没有去获取一个值;所以这里才会报错!
**总结:**遇到这种问题要么是controller中查询数据时出了问题使得HTML中获取不到;要么就是HTML中thymelefa语法有问题,只要仔细检查thymelefa语法即可。
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦