Spring项目处理分页(逻辑和物理分页)

处理分页问题

分页问题总分为物理分页和逻辑分页两大类。物理(SQL)分页又有pagehelper分页插件、lambda函数分页最为普遍;逻辑分页很少使用,因为当处理数据超过10万条以后可能会超载。


                    **老铁们点个赞吧,给小白点鼓励!**


前言

每次pagehelper分页出问题,遇到苦笔的分页问题都去百度,全都是pagehelper分页的不同工具类的使用,最后解决问题的办法还是依赖强大的SQL函数。


提示:以下是逻辑分页和物理分页的总括图

在这里插入图片描述


一、物理分页

物理分页依赖的是某一物理实体,这个物理实体就是数据库,比如MySQL数据库提供了limit关键字,程序员只需要编写带有limit关键字的SQL语句,数据库返回的就是分页结果。

1.pagehelper分页

  1. spring是三层架构,controller层是接收前端的持久层,分页也一般是在这一层处理。
  2. pagehelper仅仅是对从servise层中的第一条查询SQL返回的数据进行分页。
  3. servise层不能改变从DAO层获取的List长度,只能改变list中的元素

    导入maven的pagehelper插件为

强烈推荐阅读——浅析pagehelper分页原理

<dependency>
   <groupId>com.github.pagehelper</groupId>
   <artifactId>pagehelper</artifactId>
   <version>4.1.6</version>
</dependency>

controller层pagehelper应用的代码为

int pageNum;
int pageSize;
if (map.get("pageNum") == null || map.get("pageNum") == "") {
pageNum = 1;
} else {
pageNum = Integer.parseInt(map.get("pageNum").toString());
}
if (map.get("pageSize") == null || map.get("pageSize") == "") {
pageSize = 10;
} else {
pageSize = Integer.parseInt(map.get("pageSize").toString());
}
PageHelper.startPage(pageNum, pageSize);
List<PageData> appUserList = memberConsoleService.appUserList(map);
PageInfo<PageData> page = new PageInfo<PageData>(appUserList, pageSize);
return R.ok().put("list", appUserList).put("count", page.getTotal());

2.lambda函数分页

lambda函数是java8才有的新特性,lambda函数与pagehelper分页都是SQL分页。

  1. lambda函数仅仅是对从servise层中的最后一条查询SQL返回的数据进行分页。
  2. servise层不能改变从DAO层获取的List长度,只能改变list中的元素
  3. 这两种方法都有很明显的缺点,缺没有办法,害
    lambda函数在controller层的应用为
int pageIndex;
int pageSize;
if (map.get("pageSize") != null && map.get("pageNum") != null && !"".equals(map.get("pageSize"))
				&& !"".equals(map.get("pageNum"))) {
    pageIndex = Integer.parseInt(map.get("pageNum").toString());// 当前页 前端传
    pageSize = Integer.parseInt(map.get("pageSize").toString());// 每页显示条数 前端传
		} else {
                pageIndex = 1;// 当前页 前端传
                pageSize = 10;// 每页显示条数 前端传
		}
List<Map<String, Object>> List = firstAccountservice.querySystemAnnouncementList(map);
int total = (int) List.stream().filter(s -> !s.isEmpty()).count();// 总条数
List<Map<String, Object>> collect = List.stream().skip(pageSize * (pageIndex - 1)).limit(pageSize)
				.collect(Collectors.toList());// 数据
return R.ok().put("list", collect).put("count", total);

3.MySQL中limit函数

limit是MySQL内置函数,其作用是用于限制du查询结果的条数。

  1. 查询的语法:SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
  2. select * from table limit 5; --返回前5行
  3. select * from table limit 0,5; --同上,返回前5行
  4. select * from table limit 5,10; --返回6-15行
    现在查到的limit函数的应用以及详解都差不多,也不知道谁抄谁的,我就推荐一个你们可以去看看(主要是我也没怎么用)

mysql分页——Mysql中limit的语法

二、逻辑分页

逻辑分页依赖的是程序员编写的代码。数据库返回的不是分页结果,而是全部数据,然后再由程序员通过代码获取分页数据,常用的操作是一次性从数据库中查询出全部数据并存储到List集合中,因为List集合有序,再根据索引获取指定范围的数据。

1.逻辑分页详解

  1. 逻辑分页显示从servise层获取的全部数据放到内存中,然后在controller层进行分页。
  2. 相对于物理分页,逻辑分页的工具包更多,我这里有一个搜到的工具包,分享给你们看看

逻辑分页的工具包:

package com.intelsrc.bean;

import java.util.List;
@SuppressWarnings("unchecked")
public class PageBean {
	
	private List list ;
	private int allRow;
	private int totalPage;
	public int getTotalPage() {
		return totalPage;
	}
	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}
	private int currentPage;
	private int pageSize;
	
	
	private boolean isFirstPage;

	private boolean isLastPage;
	
	private boolean hasNextPage;
	
	private boolean hasPreviousPage;
	
	@SuppressWarnings("unchecked")
	public List getList() {
		return list;
	}
	@SuppressWarnings("unchecked")
	public void setList(List list) {
		this.list = list;
	}
	public int getAllRow() {
		return allRow;
	}
	public void setAllRow(int allRow) {
		this.allRow = allRow;
	}
	
	public int getCurrentPage() {
		return currentPage;
	}
	public void setCurrentPage(int currentPage) {
		this.currentPage = currentPage;
	}
	public int getPageSize() {
		return pageSize;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	
	

	
	public void init(){
		this.isFirstPage=this.isFirstPage();
		this.isLastPage=this.isLastPage();
		this.hasNextPage=this.isHasNextPage();
		this.hasPreviousPage=this.isHasPreviousPage();
		
	}
	
	public boolean isFirstPage() {
		return currentPage==1;
	}
	public boolean isLastPage() {
		return currentPage==totalPage;
	}
	public boolean isHasNextPage() {
		return currentPage!=1;
	}
	public boolean isHasPreviousPage() {
		return currentPage!=totalPage;
	}
	/**
	 * 计算总页数,静态方法,供外部直接通过类名调用
	 * @param pageSize
	 * @param allRow
	 * @return 总页数
	 */
	public static int countToltalPage(final int pageSize,int allRow){
		int toltalPage=allRow%pageSize==0?allRow/pageSize:allRow/pageSize+1;
		return toltalPage;
	}
	/**
	 * 计算当前页开始记录
	 * @param pageSize
	 * @param currentPage
	 * @return  当前页开始记录号
	 */
	public static int countOffset(final int pageSize,final int currentPage){
		final int offset=pageSize*(pageSize-1);
		return offset;
		
	}
	/**
	 * 计算当前页,若为0或者请求的URL中没有"?page=",则用1代替。
	 * @param page  page 传入的参数(可能为空,即0,则返回1)
	 * @return 当前页
	 */
	public static int countCurrentPage(int page){
        final int curPage = (page==0?1:page);
        return curPage;
    }

}

总结:两种分页的区别

分页的引用:物理和逻辑分页

物理分页相比于逻辑分页不会造成内存溢出,但翻页的数据相比于逻辑分页又慢,所以根据实际情况选择分页方式,如果数据量不大,可以考虑使用逻辑分页使翻页速度加快。。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值