分页和多条件查询功能

时间:2022-09-16 11:17:39
/**
* 辅助拼接HQL语句的工具类
* @author G-Xia
*
*/
public class QueryHelper {

private String fromClause; // From子句
private String whereClause = ""; // Where子句
private String orderByClause = ""; // OrderBy子句

private List<Object> parameters = new ArrayList<Object>(); // 参数列表

/**
* 生成From子句
*
* @param clazz
* @param alias
* 别名
*/
public QueryHelper(Class clazz, String alias) {
fromClause = "FROM " + clazz.getSimpleName() + " " + alias;
}

/**
* 拼接Where子句
*
* @param condition
* @param args
*/
public QueryHelper addWhereCondition(String condition, Object... args) {
// 拼接
if (whereClause.length() == 0) {
whereClause = " WHERE " + condition;
} else {
whereClause += " AND " + condition;
}
// 处理参数
if (args != null && args.length > 0) {
for (Object arg : args) {
parameters.add(arg);
}
}
return this;
}

/**
* 如果第一个参数的值为true,就拼接Where子句
*
* @param append
* @param condition
* @param args
*/
public QueryHelper addWhereCondition(boolean append, String condition, Object... args) {
if (append) {
addWhereCondition(condition, args);
}
return this;
}

/**
* 拼接OrderBy子句
*
* @param propertyName
* @param asc
* true表示升序,false表示降序
*/
public QueryHelper addOrderByProperty(String propertyName, boolean asc) {
if (orderByClause.length() == 0) {
orderByClause = " ORDER BY " + propertyName + (asc ? " ASC" : " DESC");
} else {
orderByClause += ", " + propertyName + (asc ? " ASC" : " DESC");
}
return this;
}

/**
* 如果第一个参数的值为true,就拼接OrderBy子句
*
* @param append
* @param propertyName
* @param asc
*/
public QueryHelper addOrderByProperty(boolean append, String propertyName, boolean asc) {
if (append) {
addOrderByProperty(propertyName, asc);
}
return this;
}

/**
* 获取查询数据列表的HQL语句
*
* @return
*/
public String getQueryListHql() {
return fromClause + whereClause + orderByClause;
}

/**
* 获取查询总记录数的HQL语句(没有OrderBy子句)
*
* @return
*/
public String getQueryCountHql() {
return "SELECT COUNT(*) " + fromClause + whereClause;
}

/**
* 获取参数列表
*
* @return
*/
public List<Object> getParameters() {
return parameters;
}

/**
* 准备PageBean对象到Struts2的栈顶
* @param service
* @param pageNum
*/
public void preparePageBean(DaoSupport<?> service, int pageNum){
PageBean pageBean = service.getPageBean(pageNum, this);
ActionContext.getContext().getValueStack().push(pageBean);
}
}

PageBean:分页用的页面信息

public class PageBean {

// 传递的参数或配置的值
private int currentPage; // 当前页
private int pageSize; // 每页显示的记录数

// 查询数据库
private int recordCount; // 总记录数
private List recordList; // 本页的数据列表

// 计算出来的
private int pageCount; // 总页数
private int beginPageIndex; // 页面列表的开始索引
private int endPageIndex; // 页面列表的结束索引

/**
* 只接受前4个必要的属性的值,会自动的计算出后3个属性的值
*
* @param currentPage
* @param pageSize
* @param recordCount
* @param recordList
*/
public PageBean(int currentPage, int pageSize, int recordCount, List recordList) {
this.currentPage = currentPage;
this.pageSize = pageSize;
this.recordCount = recordCount;
this.recordList = recordList;

// 计算pageCount
pageCount = (recordCount + pageSize - 1) / pageSize;

// 计算begPageIndex和endPageIndex
// a, 总页数不超过10页,就全部显示
if (pageCount <= 10) {
beginPageIndex = 1;
endPageIndex = pageCount;
}
// b, 总页数超过了10页,就显示当前页附近的共10个页码(前4个 + 当前页 + 后5个)
else {
// 显示当前页附近的共10个页码(前4个 + 当前页 + 后5个)
beginPageIndex = currentPage - 4; // 7 - 4 = 3
endPageIndex = currentPage + 5; // 7 + 5 = 12
// 当前面不足4个页码时,就显示前10页
if (beginPageIndex < 1) {
beginPageIndex = 1;
endPageIndex = 10;
}
// 当后面不足5个页码时,就显示后10页
else if (endPageIndex > pageCount) {
endPageIndex = pageCount;
beginPageIndex = pageCount - 10 + 1; // 注意在显示的时候是包含两个边界的
}
}
}

public int getCurrentPage() {
return currentPage;
}

public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}

public int getPageCount() {
return pageCount;
}

public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}

public int getPageSize() {
return pageSize;
}

public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}

public int getRecordCount() {
return recordCount;
}

public void setRecordCount(int recordCount) {
this.recordCount = recordCount;
}

public List getRecordList() {
return recordList;
}

public void setRecordList(List recordList) {
this.recordList = recordList;
}

public int getBeginPageIndex() {
return beginPageIndex;
}

public void setBeginPageIndex(int beginPageIndex) {
this.beginPageIndex = beginPageIndex;
}

public int getEndPageIndex() {
return endPageIndex;
}

public void setEndPageIndex(int endPageIndex) {
this.endPageIndex = endPageIndex;
}

}


/**
* 公共的查询分页信息的方法(最终版)
*
* @param pageNum
* @param queryHelper
* 查询语句 + 参数列表
* @return
*/
public PageBean getPageBean(int pageNum, QueryHelper queryHelper) {
System.out.println("------------> DaoSupportImpl.getPageBean( int pageNum, QueryHelper queryHelper )");

// 获取pageSize等信息
int pageSize = Configuration.getPageSize();
List<Object> parameters = queryHelper.getParameters();

// 查询一页的数据列表
Query query = getSession().createQuery(queryHelper.getQueryListHql());
if (parameters != null && parameters.size() > 0) { // 设置参数
for (int i = 0; i < parameters.size(); i++) {
query.setParameter(i, parameters.get(i));
}
}
query.setFirstResult((pageNum - 1) * pageSize);
query.setMaxResults(pageSize);
List list = query.list(); // 查询

// 查询总记录数
query = getSession().createQuery(queryHelper.getQueryCountHql()); // 注意空格!
if (parameters != null && parameters.size() > 0) { // 设置参数
for (int i = 0; i < parameters.size(); i++) {
query.setParameter(i, parameters.get(i));
}
}
Long count = (Long) query.uniqueResult(); // 查询

return new PageBean(pageNum, pageSize, count.intValue(), list);
}

// 准备分页的数据 -- 使用QueryHelper
new QueryHelper(Topic.class, "t")//
.addWhereCondition("t.forum=?", forum)//
.addWhereCondition((viewType == 1), "t.type=?", Topic.TYPE_BEST) // 1 表示只看精华帖
.addOrderByProperty((orderBy == 1), "t.lastUpdateTime", asc) // 1 表示只按最后更新时间排序
.addOrderByProperty((orderBy == 2), "t.postTime", asc) // 表示只按主题发表时间排序
.addOrderByProperty((orderBy == 3), "t.replyCount", asc) // 表示只按回复数量排序
.addOrderByProperty((orderBy == 0), "(CASE t.type WHEN 2 THEN 2 ELSE 0 END)", false)//
.addOrderByProperty((orderBy == 0), "t.lastUpdateTime", false) // 0 表示默认排序(所有置顶帖在前面,并按最后更新时间降序排列)
.preparePageBean(topicService, pageNum);

JSP中页面信息

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>

<%-- 分页信息 --%>
<div id=PageSelectorBar>
<div id=PageSelectorMemo>
页次:${currentPage}/${pageCount }页  
每页显示:${pageSize }条  
总记录数:${recordCount }条
</div>
<div id=PageSelectorSelectorArea>

<a href="javascript: gotoPage(1)" title="首页" style="cursor: hand;">
<img src="${pageContext.request.contextPath}/style/blue/images/pageSelector/firstPage.png"/>
</a>

<%-- 页码列表 --%>
<s:iterator begin="%{beginPageIndex}" end="%{endPageIndex}" var="num">
<s:if test=" #num != currentPage "><%-- 非当前页,有链接 --%>
<span class="PageSelectorNum" style="cursor: hand;" onClick="gotoPage(${num});">${num}</span>
</s:if>
<s:else><%-- 当前页,没有链接 --%>
<span class="PageSelectorNum PageSelectorSelected">${num}</span>
</s:else>
</s:iterator>

<a href="javascript: gotoPage(${pageCount})" title="尾页" style="cursor: hand;">
<img src="${pageContext.request.contextPath}/style/blue/images/pageSelector/lastPage.png"/>
</a>

转到:
<select id="pn" onchange="gotoPage( this.value )">
<s:iterator begin="1" end="%{pageCount}" var="num">
<option value="${num}">${num}</option>
</s:iterator>
</select>

<%-- 让select默认选中当前页 --%>
<script type="text/javascript">
$("#pn").val( "${currentPage}" );
</script>

</div>
</div>

<script type="text/javascript">
/**
* 转到指定的页码
* @param {Object} pageNum
*/
function gotoPage( pageNum ){
// 方式一:
// window.location.href = "forum_show.do?id=${id}&pageNum=" + pageNum;
// alert("请实现gotoPage()方法!");
// 方式二:
$("#pageForm").append("<input type='hidden' name='pageNum' value='" + pageNum + "'>"); // 添加pageNum表单字段
$("#pageForm").submit(); // 提交表单
}
</script>



相关文章