使用PageHelper实现分页查询(详细)

使用PageHelper实现分页查询(详细):

实现环境:

语言编程工具框架分页插件前端前端数据获取
JavaIDEASpringBootpageHelperBootStrapThymeleaf

**项目背景:**我们需要在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
@NoArgsConstructor
public class User {
    int id;
    String name;
    int age;
    String pwd;
}

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容器
@Mapper
public interface UserMapper {

    //通过注解查询出全部数据
    @Select("select * from user")
    List<User> queryUser();
}

4、创建业务层接口userService:

package com.example.pagehelper.service;

import com.example.pagehelper.pojo.User;

import java.util.List;

public interface userService {
    List<User> queryUser();
}

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();
    }
}

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;

@Controller
public class userController {

    @Resource
    private userServiceImpl userService;

    @RequestMapping("/user")
    public String queryUser(Model model){
        List<User> users = userService.queryUser();
        model.addAttribute("user",users);
        return "allUser";
    }
}

7、配置application.properties配置文件:

#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

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>

此时我们整个项目的全部显示就算是完成了(以上代码会出现一个问题,解决方法可见文末!!!)

在这里插入图片描述

到此我们的显示就没问题了,接下来我们再实现分页显示。

二、实现分页显示

这里我们通过 pagehelper 插件来实现分页显示:

官方使用文档:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md

1、导包:

我们要使用PageHelper插件的话,需要先在pom文件中导入相关的依赖包。

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.3</version>
</dependency>

2、配置application.properties:

#pagehelper配置
pagehelper.helper-dialect=mysql
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
pagehelper.params=count=countSql

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方法和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));

4、userServiceImpl类:

前面的User类,UserMapper以及userService都不需要更改,我们直接在userServiceImpl中添加分页查询的方法即可。

    //分页查询功能
    public List<User> queryUserByPage(Integer pageNum,Integer pageSize){
        PageHelper.startPage(pageNum,pageSize);
        return userMapper.queryUser();
    }

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";
    }

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>

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]")

如果出现找不到html资源的错误,可能是因为我们在使用 thymeleaf 时出现错误,如获取controller传过来的数据时等等;此时我们应该仔细检查一下在使用 thymeleaf 的过程中是否有语法错误。

在上述代码中,我们就会出现一个这样的问题:

首先,此时我们可以先考虑是不是在controller查询的时候出了问题,我们可以在controller中输出一下我们查询出来的数据:

在这里插入图片描述

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

然后我们查看HTML代码:
在这里插入图片描述
这里可以发现,我们在a标签中多写了两个 th: ,且后面没有去获取一个值;所以这里才会报错!

**总结:**遇到这种问题要么是controller中查询数据时出了问题使得HTML中获取不到;要么就是HTML中thymelefa语法有问题,只要仔细检查thymelefa语法即可。

  • 52
    点赞
  • 355
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
PageHelper是一个用于实现分页查询的框架。通过提供页码和每页条数,PageHelper可以自动实现分页效果,并收集分页信息。它的原理是在程序运行时,拦截SQL语句,在语句尾部添加limit关键字,并按照分页信息向limit后追加分页数据。 在控制层的代码中,可以看到对PageHelper使用。通过@GetMapping和@ApiImplicitParams注解,配置了分页查询的接口。其中,page参数表示页码,pageSize参数表示每页的条数。通过调用orderService.getAllStudentsByPage方法,实现分页查询,并将查询结果封装到PageInfo对象中。最后,返回JsonResult对象,携带分页查询的结果信息。 综上所述,PageHelper是一个方便实现分页查询的框架,通过配置页码和每页条数,自动实现分页效果,并收集分页信息。在控制层中,可以通过调用getAllStudentsByPage方法,实现分页查询,并返回查询结果和分页信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [pagehelper实现分页查询](https://blog.csdn.net/Suphans/article/details/128891071)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值