public interface Page<T> {
/**
* @return 是否是首页(第一页),第一页页码为1
*/
public boolean isFirst();
/**
* @return 是否是最后一页
*/
public boolean isLast();
/**
* @return 是否有下一页
*/
public boolean hasNext();
/**
* @return 是否有上一页
*/
public boolean hasPrevious();
/**
* @return 当前页的数据内容
*/
public List<T> getThisPageElements();
/**
* @return 数据总的条目数量
*/
public int getTotalNumberOfElements();
/**
* @return 当前页的首条数据的行编码
*/
public int getFirstElementNumber();
/**
* @return 当前页的末条数据的行编码
*/
public int getLastElementNumber();
/**
* @return 当前页编码
*/
public int getPageNumber();
/**
* @return 下一页编码
*/
public int getNextPageNumber();
/**
* @return 上一页编码
*/
public int getPreviousPageNumber();
/**
* @return 获取最后一页页码,也就是总页数
*/
public int getLastPageNumber();
/**
* @return 每一页显示的条目数
*/
public int getPageSize();
}
基于Hibernate的实现:
public class HibernatePage<T> implements Page<T> {
private List<T> elements;
private int pageSize;
private int pageNumber;
private int totalElements = 0;
/**
* 构建HibernatePage对象,完成Hibernate的Query数据的分页处理
*
* @param query
* Hibernate的Query对象
* @param pageNumber
* 当前页编码,从1开始,如果传的值为Integer.MAX_VALUE表示获取最后一页。
* 如果你不知道最后一页编码,传Integer.MAX_VALUE即可。如果当前页超过总页数,也表示最后一页。
* 这两种情况将重新更改当前页的页码,为最后一页编码。
* @param pageSize
* 每一页显示的条目数
*/
public HibernatePage(Query query, int pageNumber, int pageSize) {
this.pageNumber = pageNumber;
this.pageSize = pageSize;
try {
ScrollableResults scrollableResults = query.scroll();
// get the total elements number
scrollableResults.last();
this.totalElements = scrollableResults.getRowNumber();
if (Integer.MAX_VALUE == this.pageNumber || this.pageNumber > getLastPageNumber()) // last page
{
this.pageNumber = getLastPageNumber();
}
elements = query.setFirstResult(
(this.pageNumber - 1) * this.pageSize).setMaxResults(
this.pageSize + 1).list();
} catch (HibernateException e) {
throw new RuntimeException(e);
}
}
public boolean isFirst() {
return getPageNumber() == 1;
}
public boolean isLast() {
return getPageNumber() >= getLastPageNumber();
}
public boolean hasNext() {
return getLastPageNumber() > getPageNumber();
}
public boolean hasPrevious() {
return getPageNumber() > 1;
}
public int getLastPageNumber() {
return totalElements % this.pageSize == 0 ? totalElements / this.pageSize : totalElements / this.pageSize + 1;
}
/**
* 返回List类型数据
*
* @return List数据源
*/
public List<T> getThisPageElements() {
return elements;
}
public int getTotalNumberOfElements() {
return totalElements;
}
public int getFirstElementNumber() {
return (getPageNumber() - 1) * getPageSize() + 1;
}
public int getLastElementNumber() {
int fullPage = getFirstElementNumber() + getPageSize() - 1;
return getTotalNumberOfElements() < fullPage ? getTotalNumberOfElements()
: fullPage;
}
public int getNextPageNumber() {
return getPageNumber() + 1;
}
public int getPreviousPageNumber() {
return getPageNumber() - 1;
}
public int getPageSize() {
return pageSize;
}
public int getPageNumber() {
return pageNumber;
}
}
基于JPA的实现:
public class JPAPage<T> implements Page<T> {
private List<T> elements;
private Integer pageSize;
private Integer pageNumber;
private Integer totalElements = 0;
/**
* 构建JPAPage对象,完成JPAPage的Query数据的分页处理
*
* @param countQuery
* Hibernate的查询总数的Query对象
* @param pageNumber
* 当前页编码
* @param pageSize
* 每一页显示的条目数
* @param dataQuery
* Hibernate的查询结果的Query对象
*/
public JPAPage(Query countQuery, int pageNumber, int pageSize,
Query dataQuery) {
// 设置
this.pageSize = pageSize;
this.pageNumber = pageNumber;
// 验证
if (this.pageNumber < 1) {
this.pageNumber = 1;
}
if (Integer.MAX_VALUE == this.pageNumber || this.pageNumber > getLastPageNumber()) // last page
{
this.pageNumber = getLastPageNumber();
}
// 注入数据
try {
Object obj = countQuery.getSingleResult();
if (obj != null && obj instanceof Long) {
this.totalElements = ((Long) obj).intValue();
} else {
throw new NumberFormatException("[countQuery is error.]");
}
elements = dataQuery.setFirstResult(
(this.pageNumber - 1) * this.pageSize).setMaxResults(
this.pageSize + 1).getResultList();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public boolean isFirst() {
return getPageNumber() == 1;
}
public boolean isLast() {
return getPageNumber() >= getLastPageNumber();
}
public boolean hasNext() {
return getLastPageNumber() > getPageNumber();
}
public boolean hasPrevious() {
return getPageNumber() > 1;
}
public int getLastPageNumber() {
return totalElements % this.pageSize == 0 ? totalElements / this.pageSize : totalElements / this.pageSize + 1;
}
/**
* 返回List类型数据
*
* @return List数据源
*/
public List<T> getThisPageElements() {
return elements;
}
public int getTotalNumberOfElements() {
return totalElements + 1;
}
public int getFirstElementNumber() {
return (getPageNumber() - 1) * getPageSize() + 1;
}
public int getLastElementNumber() {
int fullPage = getFirstElementNumber() + getPageSize() - 1;
return getTotalNumberOfElements() < fullPage ? getTotalNumberOfElements()
: fullPage;
}
public int getNextPageNumber() {
return getPageNumber() + 1;
}
public int getPreviousPageNumber() {
return getPageNumber() - 1;
}
public int getPageSize() {
return pageSize;
}
public int getPageNumber() {
return pageNumber;
}
}
同样,基于JDBC的实现或者其他什么数据结构查询的实现都很简单。使用Freemarker/Velocity分页宏编写也很容易。
这个分页虽然粗糙,但是一般的应用足够了,不过在排序方面还有待改进。