4、PageHelper分页查询

千里之行,始于足下

 


正文

回到顶部

1、MyBatis的分页方式:

逻辑分页与物理分页

1、逻辑分页:使用MyBatis自带的RowBounds进行分页,是一次性查询很多数据,然后再在结果中检索分页的数据。这样做弊端是需要消耗大量的内存、有内存溢出的风险、对数据库压力较大。

2、物理分页:使用分页插件PageHelper或者自己写sql分页(limit),是从数据库查询指定条数的数据,弥补了一次性全部查出的所有数据的种种缺点,比如需要大量的内存,对数据库查询压力较大等问题。

回到顶部

2、PageHelper的原理:

PageHelper是MyBatis提供的分页插件;首先是在Mybatis里面配置了分页拦截器(PageInterceptor),即在执行相关Sql之前会拦截做一点事情;通过setLocalPage()方法,将分页信息保存在当前线程中。查询方法与之处于同一个线程中,共享ThreadLocal中的数据。selectlist查询之后赋值给的List list。这个list是Page 类型。再将list放到PageInfo<>中即可。

回到顶部

3、PageHelper分页实现:

回到顶部

(1)、建工程:

建立Springboost工程;

回到顶部

(2)、改POM:

复制代码
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!--SpringBoot框架web项目起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!--lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
            <optional>true</optional>
        </dependency>

        <!--PageHelper插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.4.2</version>
        </dependency>
    </dependencies>
复制代码
回到顶部

(3)、写YML:

复制代码
server:
  port: 8081

spring:
  application:
    name: pagehelperdemo
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource    #当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver    #mysql驱动包
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
    druid:
      test-while-idle: false  #关闭空闲检测

mybatis:
  mapperLocations: classpath:mapper/*.xml    #resources下建mapper包
复制代码
回到顶部

(4)、业务类:

复制代码
    //实现类 
   @Autowired
    private PageDemoMapper pageDemoMapper;

    /**
     * PageHelper分页查询
     * @Param pageNum:页数
     * @Param pageSize:每页显示的条目
     * */
    @Override
    public PageInfo<PageDemo> selectPage(Integer pageNum , Integer pageSize) {
        log.info("页数:"+pageNum);
        log.info("每页显示的条目:"+pageSize);
        //查询数据库的时候会自动加上limit
        //PageDemoMapper: List<PageDemo> selectAllDemo();
        return PageHelper.startPage(pageNum, pageSize)
                .doSelectPageInfo(() -> pageDemoMapper.selectAllDemo());
    }    
复制代码
回到顶部

 4、自定义分页工具类:

复制代码
import com.github.pagehelper.PageInfo;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;


public class PageHelperUtil {

    /**
     * @Description: @description: 自定义分页工具类
     * @param pageNum 当前页
     * @param pageSize 每页显示的数目
     * @param list 总数据
     */
    public static <T> PageInfo<T> initPageInfo(int pageNum, int pageSize, List<T> list) {
        if(ObjectUtils.isEmpty(list)){
            PageInfo<T> pageInfo = new PageInfo<>(new ArrayList<>());
            // 当前页
            pageInfo.setPageNum(pageNum);
            // 每页的数量
            pageInfo.setPageSize(pageSize);
            return pageInfo;
        }
        int total = list.size();
        // 默认如果当前页小于0则为第一页
        pageNum = pageNum <= 0 ? 1 : pageNum;
        // 默认如果当前页大于最大的页数为当前页
        pageNum = pageNum > (total + pageSize - 1) / pageSize ? (total + pageSize - 1) / pageSize : pageNum;
        // 将需要分页的数组进行截取处理
        int fromIndex = 0;
        int toIndex = 0;
        if (total / pageSize == 0 && total % pageSize > 0) {
            // 表示当前数据只有一页
            fromIndex = 0;
            toIndex = total;
        } else if (total / pageSize >= 1 && total % pageSize >= 0) {
            // 超过一页
            fromIndex = (pageNum - 1) * pageSize;
            toIndex = pageNum * pageSize >= total ? total : pageSize * pageNum;
        }
        List<T> tempList = list.subList(fromIndex, toIndex);// 真正需要分页显示的数据
        PageInfo<T> pageInfo = new PageInfo<>(tempList);// 结果集(每页显示的数据)
        pageInfo.setPageNum(pageNum);// 当前页
        pageInfo.setPageSize(pageSize);// 每页的数量
        pageInfo.setSize(tempList.size());// 当前页的数量
        pageInfo.setStartRow(0);// 当前页面第一个元素在数据库中的行号
        pageInfo.setEndRow(tempList.size() > 0 ? tempList.size() - 1 : 0);// 当前页面最后一个元素在数据库中的行号
        pageInfo.setTotal(total);// 总记录数
        pageInfo.setPages((total + pageSize - 1) / pageSize);// 总页数
        calcNavigatepageNums(pageInfo);// 计算导航页
        calcPage(pageInfo);// 计算前后页,第一页,最后一页
        judgePageBoudary(pageInfo);// 判断页面边界
        if (pageInfo.getList() == null) {
            pageInfo.setList(new ArrayList<>());
        }
        return pageInfo;
    }

    /**
     * 计算导航页
     */
    private static <T> void calcNavigatepageNums(PageInfo<T> pageInfo) {
        int pages = pageInfo.getPages();
        int navigatePages = pageInfo.getNavigatePages();
        int pageNum = pageInfo.getPageNum();
        // 当总页数小于或等于导航页码数时
        if (pages <= navigatePages) {
            pageInfo.setNavigatepageNums(new int[pages]);
            for (int i = 0; i < pages; i++) {
                pageInfo.getNavigatepageNums()[i] = i + 1;
            }
        } else { // 当总页数大于导航页码数时
            pageInfo.setNavigatepageNums(new int[navigatePages]);
            int startNum = pageNum - navigatePages / 2;
            int endNum = pageNum + navigatePages / 2;

            if (startNum < 1) {
                startNum = 1;
                // (最前navigatePages页
                for (int i = 0; i < navigatePages; i++) {
                    pageInfo.getNavigatepageNums()[i] = startNum++;
                }
            } else if (endNum > pages) {
                endNum = pages;
                // 最后navigatePages页
                for (int i = navigatePages - 1; i >= 0; i--) {
                    pageInfo.getNavigatepageNums()[i] = endNum--;
                }
            } else {
                // 所有中间页
                for (int i = 0; i < navigatePages; i++) {
                    pageInfo.getNavigatepageNums()[i] = startNum++;
                }
            }
        }
    }

    /**
     * 计算前后页,第一页,最后一页
     */
    private static <T> void calcPage(PageInfo<T> pageInfo) {
        int[] navigatepageNums = pageInfo.getNavigatepageNums();
        int pageNum = pageInfo.getPageNum();
        int pages = pageInfo.getPages();
        if (navigatepageNums != null && navigatepageNums.length > 0) {
            pageInfo.setFirstPage(navigatepageNums[0]);
            pageInfo.setLastPage(navigatepageNums[navigatepageNums.length - 1]);
            if (pageNum > 1) {
                pageInfo.setPrePage(pageNum - 1);
            }
            if (pageNum < pages) {
                pageInfo.setNextPage(pageNum + 1);
            }
        }
    }

    /**
     * 判定页面边界
     */
    private static <T> void judgePageBoudary(PageInfo<T> pageInfo) {
        int pageNum = pageInfo.getPageNum();
        int pages = pageInfo.getPages();
        pageInfo.setIsFirstPage(pageNum == 1);
        pageInfo.setIsLastPage(pageNum == pages);
        pageInfo.setHasPreviousPage(pageNum > 1);
        pageInfo.setHasNextPage(pageNum < pages);
    }

}
复制代码

 

posted on   爱文(Iven)  阅读(497)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示

目录导航