Java分页查询的几种实现方法
Posted Oliver_Liuqifan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java分页查询的几种实现方法相关的知识,希望对你有一定的参考价值。
最近在做需求的过程中遇到几个需要分页查询的需求,我也对分页有了较深的了解。分页一般分为两种一种是直接在sql中分页,一种是在内存中分页。本文仅针对内存中分页做记录。
第一种
如果是一个查询接口,向接口中传入page,和size(page默认值1,size默认值10)即可,返回参数是github的PageInfo,里面在放实际返回类型。
进入实现层,使用PageHelper,并调用pageQuery方法即可完成分页,以下为Pagehelper的具体代码 。(但需注意,此方法只适用于从数据库中直接查出的数据,如果将查出的数据进行二次封装则会导致分页失败)
import com.github.pagehelper.Page; import lombok.experimental.UtilityClass; import org.springframework.beans.BeanUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import java.util.List; import java.util.Objects; import java.util.function.Supplier; /** * @author LIUQIFAN */ @UtilityClass public class PageHelper /** * 要求 请求参数: ?pageNum=xxx&pageSize=xxx * * @param supplier 查询方法 * @param <T> 类型对象 * @return 结果集 */ public static <T> PageInfo<T> pageQuery(Supplier<List<T>> supplier) ServletRequestAttributes attributes = (ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes(), "无法获取request"); Page<Object> page = com.github.pagehelper.PageHelper.startPage(attributes.getRequest()); //======================== List<T> list = supplier.get(); PageInfo<T> pageInfo = new PageInfo<>(); BeanUtils.copyProperties(page.toPageInfo(), pageInfo); pageInfo.setList(list); return pageInfo; /** * @param pageNum 页号 * @param pageSize 每页数据大小 * @param <T> 类型 * @return 结果集 */ public static <T> PageInfo<T> pageQuery(int pageNum, int pageSize, Supplier<List<T>> supplier) Page<Object> page = com.github.pagehelper.PageHelper.startPage(pageNum, pageSize, true); List<T> list = supplier.get(); PageInfo<T> pageInfo = new PageInfo<>(); BeanUtils.copyProperties(page.toPageInfo(), pageInfo); pageInfo.setList(list); return pageInfo; /** * @param supplier 查询方法 * @param <T> 类型对象 * @return 结果集 */ public static <T> List<T> pQuery(Supplier<List<T>> supplier) ServletRequestAttributes attributes = (ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes(), "无法获取request"); com.github.pagehelper.PageHelper.startPage(attributes.getRequest()); //======================== return supplier.get(); /** * @param pageNum 页号 * @param pageSize 每页数据大小 * @param <T> 类型 * @return 结果集 */ public static <T> List<T> pQuery(int pageNum, int pageSize, Supplier<List<T>> supplier) com.github.pagehelper.PageHelper.startPage(pageNum, pageSize, true); return supplier.get();
第二种
这种方法是我第一次使用,把入参的page和size封装成了对象PageDomain
PageDomain代码如下
@Data public class PageDomain1 /** * 当前页 */ private Integer page = 1; /** * 每页数量 */ private Integer limit = 10; /** * 获取开始的数据行 */ public Integer start() return (this.page - 1) * this.limit; /** * 获取结束的数据行 */ public Integer end() return this.page * this.limit;
这是控制层代码
这是实现层代码,这里的resultList,是我们先从数据库中查出来的结果集,再用PageUtils的Startpage方法进行分页操作,最后组装PageInfo返回体
下面是PageUtils的代码
sqlalchemy和flask-sqlalchemy的几种分页方法
sqlalchemy中使用query查询,而flask-sqlalchemy中使用basequery查询,他们是子类与父类的关系
假设 page_index=1,page_size=10;所有分页查询不可以再跟first(),all()等
1.用offset()设置索引偏移量,limit()限制取出量
db.session.query(User.name).filter(User.email.like(\'%\'+email+\'%\')).limit(page_size).offset((page_index-1)*page_size) #filter语句后面可以跟order_by语句
2.用slice(偏移量,取出量)函数
db.session.query(User.name).filter(User.email.like(\'%\'+email+\'%\')).slice((page_index - 1) * page_size, page_index * page_size) #filter语句后面可以跟order_by语句
注释:此方法和第一种相同的效果。
因为:由一下内部方法可知,slice()函数第一个属性就是offset()函数值,第二个属性就是limit()函数值
@_generative(_no_statement_condition) def slice(self, start, stop): """apply LIMIT/OFFSET to the ``Query`` based on a " "range and return the newly resulting ``Query``.""" if start is not None and stop is not None: self._offset = (self._offset or 0) + start self._limit = stop - start elif start is None and stop is not None: self._limit = stop elif start is not None and stop is None: self._offset = (self._offset or 0) + start if self._offset == 0: self._offset = None @_generative(_no_statement_condition) def limit(self, limit): """Apply a ``LIMIT`` to the query and return the newly resulting ``Query``. """ self._limit = limit @_generative(_no_statement_condition) def offset(self, offset): """Apply an ``OFFSET`` to the query and return the newly resulting ``Query``. """ self._offset = offset
3.用paginate(偏移量,取出量)函数,用于BaseQuery
user_obj=User.query.filter(User.email.like(\'%\'+email+\'%\')).paginate(int(page_index), int(page_size),False) #遍历时要加上items object_list =user_obj.items
4.filter中使用limit
db.session.query(User.name).filter(User.email.like(\'%\'+email+\'%\') and limit (page_index - 1) * page_size, page_size) #此处不能再跟order_by语句,否则报错
http://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_350days.html
以上是关于Java分页查询的几种实现方法的主要内容,如果未能解决你的问题,请参考以下文章