Java分页原理简介

本文深入探讨了Java分页技术的原理与实践,包括减少网络资源消耗、改善用户体验的分页目的,以及传统分页、下拉式分页的样式对比。详细介绍了使用List接口、数据库SQL语句、数据库分页语法、Hibernate框架等多种分页实现方式,并通过具体代码示例展示了如何在实际项目中应用这些技术。

Java分页原理

分页目的

数据方面 :

  • 减少带宽和网络资源
  • 降低浏览器渲染负荷

用户体验方面

  • 更好的展示和查询信息

网站常见分页样式

  • 采用传统的分页方式(后台常用),可以明确的获取数据信息,如有多少条数据
    分多少页显示等
  • 采用下拉式的分页方式(社交网络常用),一般无法获取明确的数据数量相关的信息
    但是在分页操作以后,仍然可以看到之前査询的数据

常见的分页实现方式

  • 使用List接口中subList(int startlndex, int endlndex)方法实现分页

  • 直接使用数据库SQL语句实现分页

    利用数据库自带的分页语法,使用分页语句,获取分页数据(例如mysql数据库使用limit关键字,oracle中使用rownum关键字等)

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

    • Mysql查询语句

      • select * from t_student limit 0,10
    • Oracle査询语句

      select * from
      (
      select s.*, rownum rn
      from (select * from t_student) s
      where rownum <= 10
      )
      where rn >= 1
      
  • 使用hibernate等框架实现跨数据库的分页

    • Hibernate 创建Query或者Criteria对象,査询时,设置firstResult和maxResults 属性

      String hql = "from Student";
      Query q = session.createQuery(hql)
      q.setFirstResult(0);
      q.setMaxResults(10);
      List 1 = q.list();
      

分页实现方式比较

实现方式

模型对象
处理映射数据表的对象外,还要创建一个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数据:

package com.imooc.page.servlet;

import java.io.IOException;
import java.io.Writer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.imooc.page.Constant;
import com.imooc.page.model.Pager;
import com.imooc.page.model.Student;
import com.imooc.page.service.HibernateStudentServiceImpl;
import com.imooc.page.service.StudentService;
import com.imooc.page.util.StringUtil;

public class HibernateDataServlet extends HttpServlet {

private StudentService studentService = new HibernateStudentServiceImpl();

public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    doPost(request, response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    // 接收request里的参数
    String stuName = request.getParameter("stuName"); //学生姓名

    // 获取学生性别
    int gender = Constant.DEFAULT_GENDER;
    String genderStr = request.getParameter("gender");
    if(genderStr!=null && !"".equals(genderStr.trim())){
        gender = Integer.parseInt(genderStr);
    }

    // 校验pageNum参数输入合法性
    String pageNumStr = request.getParameter("pageNum"); 
    if(pageNumStr !=null && !StringUtil.isNum(pageNumStr)){
        request.setAttribute("errorMsg", "参数传输错误");
        request.getRequestDispatcher("jdbcSqlStudent.jsp").forward(request, response);
        return;
    }

    int pageNum = Constant.DEFAULT_PAGE_NUM; //显示第几页数据
    if(pageNumStr!=null && !"".equals(pageNumStr.trim())){
        pageNum = Integer.parseInt(pageNumStr);
    }

    int pageSize = Constant.DEFAULT_PAGE_SIZE;  // 每页显示多少条记录
    String pageSizeStr = request.getParameter("pageSize");
    if(pageSizeStr!=null && !"".equals(pageSizeStr.trim())){
        pageSize = Integer.parseInt(pageSizeStr);
    }

    // 组装查询条件
    Student searchModel = new Student(); 
    searchModel.setStuName(stuName);
    searchModel.setGender(gender);

    //调用service 获取查询结果
    Pager<Student> result = studentService.findStudent(searchModel, 
                                                            pageNum, pageSize);
    //不使用缓存
    response.setHeader("Cache-Control", "no-cache");  
    response.setHeader("Pragma", "no-cache");  
    //设置超时时间为0
    response.setDateHeader("Expires", 0);  
    //设置编码格式为utf-8
    response.setContentType("text/html;charset=utf-8");

    //获取查询数据的json格式
    String responseStr = JSON.toJSONString(result);
    //写入数据到response
    Writer writer = response.getWriter();
    writer.write(responseStr);
    writer.flush();
}

public static void main(String[] args) {
    String s = String.format("%05d", 123);
    System.out.println(s);
}
}
分页插件

参考

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值