常见的分页类型:
- 传统的:采用传统的分页方式,可以明确的获取数据信息,如有多少条数据,分多少页显示等。
- 下拉式:采用下拉式的分页方式,一般无法获取明确的数据数量相关的信息,但在分页操作以后,仍然可以看到之前查询的数据。
常见的分页实现方式:
- 使用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