Java分页原理

标签: 分页

常见的分页类型:

  • 传统的:采用传统的分页方式,可以明确的获取数据信息,如有多少条数据,分多少页显示等。
  • 下拉式:采用下拉式的分页方式,一般无法获取明确的数据数量相关的信息,但在分页操作以后,仍然可以看到之前查询的数据。

常见的分页实现方式:

  • 使用list接口中的subList(int startIndex,int endIndex)方法实现分页
  • 直接使用数据库SQL语句实现分页
  • 使用hibernate等框架实现跨数据库的分页

使用subList()实现分页

使用的是list接口中的subList(int startIndex,int endIndex)方法,返回列表中指定的fromIndex(包括)和endIndex(不包括)之间的部分视图。



使用数据库SQL语句

MySQL数据库使用limit关键字,Oracle中使用rownum关键字。

例如:从学生表(t_student)中查询出前十条数据

MySQL查询语句

            select  *  from  t_student  limit 0,10

表示的是从第0条开始取,取10条记录。

postgresql开始查询语句

                 select  *  from  t_student  limit 10 offset 0

Oracle查询语句

                select * from 

                (

                select s.*,rownum rn

                from(select * from t_student)  s

                where  rownum <=10

                )

                where rn>=1

使用hibernate框架实现跨数据库的分页

    创建query或者criteria对象,查询时,设置firstResult和maxResult属性

        String hql="from Student";

        Query q=session.createQuery(hql);

        q.setFirstResult(0);

        q.setMaxResults(10);

        List  l=q.list();


分页实现方式的比较:

实现方式优点缺点适用场景
subList简单、易用效率低无法按需批量获取数据
SQL语句简单,直接,效率高s数据库兼容性差不要求数据库兼容
hibernate框架面向对象,兼容性强复杂查询性能低兼容不同数据库

实现方式

模型对象

处理映射数据表的对象外,还要创建一个Pager分页对象,其大致的内容如下:

package com.imooc.page.model;

import java.io.Serializable;

import java.util.List;

public class Pager<T> implements Serializable {

private static final long serialVersionUID = -8741766802354222579L;

//每页显示多少条记录

private int pageSize;

//当前第几页数据

private int currentPage;

    //一共有多少条记录

private int totalRecord;

//一共多少页记录

private int totalPage;

//要显示的数据,使用泛型

private List<T> dataList;

public Pager() {

super();

}

public Pager(int pageSize, int currentPage, int totalRecord, int totalPage, List<T> dataList) {

super();

this.pageSize = pageSize;

this.currentPage = currentPage;

this.totalRecord = totalRecord;

this.totalPage = totalPage;

this.dataList = dataList;

}

public Pager(int pageNum, int pageSize, List<T> sourceList){

if (sourceList == null){

return;

}

//总记录条数

this.totalRecord = sourceList.size();

//每页显示多少条记录

this.pageSize = pageSize;

//获取总页数

this.totalPage = this.totalRecord / this.pageSize;

if (this.totalRecord % this.pageSize != 0) {

this.totalPage += 1;

}

//当前第几页数据

this.currentPage = this.totalPage < pageNum ? this.totalPage : pageNum;

//起始索引

int fromIndex = this.pageSize * (this.currentPage - 1);

//结束索引

int toIndex =this.pageSize * this.currentPage > this.totalRecord ? this.totalRecord : this.pageSize * this.currentPage;

this.dataList = sourceList.subList(fromIndex, toIndex);

}

public int getPageSize() {

return pageSize;

}

public void setPageSize(int pageSize) {

this.pageSize = pageSize;

}

public int getCurrentPage() {

return currentPage;

}

public void setCurrentPage(int currentPage) {

this.currentPage = currentPage;

}

public int getTotalRecord() {

return totalRecord;

}

public void setTotalRecord(int totalRecord) {

this.totalRecord = totalRecord;

}

public int getTotalPage() {

return totalPage;

}

public void setTotalPage(int totalPage) {

this.totalPage = totalPage;

}

public List<T> getDataList() {

return dataList;

}

public void setDataList(List<T> dataList) {

this.dataList = dataList;

}

public static long getSerialversionuid() {

return serialVersionUID;

}

}


hibernate分页

Dao的实现如下:


package com.imooc.page.dao;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;
import org.hibernate.Session;

import com.imooc.page.Constant;
import com.imooc.page.HibernateSessionFactory;
import com.imooc.page.model.Pager;
import com.imooc.page.model.Student;

public class HibernateStudentDaoImpl implements StudentDao{

    @SuppressWarnings("unchecked")
    @Override
    public Pager<Student> findStudent(Student searchModel, int pageNum, int pageSize) {
        Pager<Student> result = null;

        //存放查询参数
        Map<String, Object> paramMap = new HashMap<String, Object>();

        String stuName = searchModel.getStuName();
        int gender = searchModel.getGender();

        StringBuilder hql = new StringBuilder(" from Student where 1=1");
        StringBuilder countHql = new StringBuilder("select count(id) from Student where 1=1");

        if(stuName != null && !stuName.equals("")){
            hql.append(" and stuName like :stuName");
            countHql.append(" and stuName like :stuName");
            paramMap.put("stuName","%" + stuName + "%");
        }

        if(gender == Constant.GENDER_MALE  || gender == Constant.GENDER_FEMALE){
            hql.append(" and gender = :gender");
            countHql.append(" and gender = :gender");
            paramMap.put("gender",gender);
        }

        //起始索引
        int fromIndex = pageSize * (pageNum - 1);

        List<Student> studentList = new ArrayList<Student>();

        Session session = null;

        try {

            session = HibernateSessionFactory.getSession();
            //获取query对象
            Query hqlQuery = session.createQuery(hql.toString());
            Query countHqlQuery = session.createQuery(countHql.toString());
            //设置查询参数
            setQueryParams(hqlQuery, paramMap);
            setQueryParams(countHqlQuery, paramMap);

            //从第几条记录开始查询
            hqlQuery.setFirstResult(fromIndex);
            //一共查询多少条记录
            hqlQuery.setMaxResults(pageSize);

            //获取查询的结果
            studentList = hqlQuery.list();
            //获取总计条数
            List<?> countResult = countHqlQuery.list();

            int totalRecord = ((Number)countResult.get(0)).intValue();
            //获取总页数
            int totalPage = totalRecord / pageSize;
            if (totalRecord % pageSize != 0) {
                totalPage += 1;
            }

            //组装pager
            result  = new Pager<>(pageSize, pageNum, totalRecord, totalPage, studentList);


        } catch (Exception e) {
            throw new RuntimeException("查询所有数据异常!", e);
        }finally {
            if (session != null) {
                HibernateSessionFactory.closeSession();
            }
        }

        return result;  
    }

    /**
     * 设置查询参数
     * @param query
     * @param paramMap
     * @return
     */
    private Query setQueryParams(Query query, Map<String, Object> paramMap){
        if(paramMap != null && !paramMap.isEmpty()){
            for(Map.Entry<String, Object> param : paramMap.entrySet()){
                query.setParameter(param.getKey(), param.getValue());
            }
        }
        return query;
    }

}

对应的Servlet如下,这里使用到了fastjson返回json数据:

https://blog.csdn.net/winfredzen/article/details/52104251

版权声明:本文为shizhudufou原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/shizhudufou/article/details/79896177

智能推荐

idea基础–(7)–jsp页面Controller路径自动识别的问题“Cannot resolve controller URL ...”,Cannot resolve variable

idea之所以强大,就是强大的代码提示和联想功能,写起代码来简直不要太爽。但是这几天我发现在我的jsp页面中访问controller路径的时候不会自动提示了,对于这么严谨的我肯定要找出原因啊,哈哈。 最终效果:按住ctrl,同时点击左键会自动跳转到对应的controller代码块,爽。 需要同时满足的条件 JSP页面顶部包含如下代码: 在idea的项目设置中显示如下:  若显示的是spring a...

26_Python基础_继承

面向对象三大特性: 封装 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中 继承 实现代码的重用, 相同的代码不需要重复的编写 多态 不同的对象调用相同的方法,  产生不同的执行结果,  增加代码的灵活度 1.  单继承 1.1 概念 继承的概念:&...

循环

与任何程序设计语言一样Java利用条件语句与循环结构确定流程控制,一下总结一下Java中的循环语句: while do while for switch 对于golang来说: switch非常灵活。从第一个expr为true的case开始执行,如果case带有fallthrough,程序会继续执行下一条case,不会再判断下一条case的expr,如果之后的case都有fallthrough,d...

1638 统计只差一个字符的子串数目(动态规划)

1. 问题描述: 给你两个字符串 s 和 t ,请你找出 s 中的非空子串的数目,这些子串满足替换一个不同字符以后,是 t 串的子串。换言之,请你找到 s 和 t 串中恰好只有一个字符不同的子字符串对的数目。比方说, "computer" 和 "computation"...

websocket基本原理

HTTP中一个request只能有一个response。而且这个response也是被动的,不能主动发起 因此过去的服务端推送信息是通过客户端不停的轮询实现的 websocket是双向通信协议,提供了服务端主动推送信息的能力 需要客户端(浏览器)和服务端同时支持 如果经过代理的话,还需要代理支持,否则有些代理在长时间无通信时会自动切断连接 因此WS为了保证连接不被断掉,会发心跳 WebSocket...

猜你喜欢

mybatis+ehcache二级缓存

导入jar包 mapper.xml文件开启二级缓存 pojo类实现序列化接口 配置ehcache.xml 测试...

python+opencv实现图像拼接

任务 拍摄两张图片去除相同部分,拼接在一起 原图 结果 步骤 读取两张图片 使用sift检测关键点及描述因子 匹配关键点 处理并保存关键点 得到变换矩阵 图像变换并拼接 代码实现 扩展 这里对右边图像进行变换,右边变得模糊,可以修改代码对左边图像变换 这里只有两张图片拼接,可以封装实现多张图片拼接 可以修改代码实现上下图片的拼接...

python_sklearn机器学习算法系列之AdaBoost------人脸识别(PCA,决策树)

          注:在读本文之前建议读一下之前的一片文章python_sklearn机器学习算法系列之PCA(主成分分析)------人脸识别(k-NearestNeighbor,KNN)         本文主要目的是通过一个简单的小...

memmove函数与memcpy函数的模拟实现

memmove函数和memcpy函数都是在内存复制任意类型的,但是它俩也有区别。当源区域和目标区域有重复的,memmove函数会复制缓冲区重叠的部分,而memcpy相反,会报出未知错误。 下面给出两个函数的实现 首先,memmove函数。 实现的基本原理如下图。 具体代码如下: memcpy函数的实现很简单,就直接给出源代码了...