这篇文章将为大家详细讲解有关SSH如何实现条件查询和分页查询,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
1、QueryHelper和PageResult
QueryHelper是进行HQL查询的辅助类,而PageResult则是进行分页查询的结果类。
QueryHelper.java
package com.rk.core.utils;
import java.util.ArrayList;
import java.util.List;
public class QueryHelper {
//from子句
private String fromClause = "";
//where子句
private String whereClause = "";
//order by子句
private String orderByClause = "";
private List<Object> parameters;
//排序顺序
public static String ORDER_BY_DESC = "DESC";//降序
public static String ORDER_BY_ASC = "ASC";//升序
public QueryHelper(Class clazz,String alias){
fromClause = "FROM " + clazz.getSimpleName() + " " + alias;
}
public void addCondition(String condition, Object... params){
if(whereClause.length() > 1){ //非第一个查询条件
whereClause += " AND " + condition;
}
else{//第一个查询条件
whereClause += " WHERE " + condition;
}
//设置 查询条件值 到 查询条件值集合 中
if(parameters == null){
parameters = new ArrayList<Object>();
}
if(params != null){
for(Object param : params){
parameters.add(param);
}
}
}
public void addOrderByProperty(String property, String order){
if(orderByClause.length()>1){ //非第一个排序属性
orderByClause += ", " + property + " " + order;
}
else{ //第一个排序属性
orderByClause = " ORDER BY " + property + " " + order;
}
}
//查询hql语句
public String getQueryListHql(){
return fromClause + whereClause + orderByClause;
}
//查询统计数的hql语句
public String getQueryCountHql(){
return "SELECT COUNT(*) " + fromClause + whereClause;
}
//查询hql语句中对应的查询条件值集合
public List<Object> getParameters(){
return parameters;
}
}
QueryHelper分析:由3部分组成
(1)from子句
(2)where子句
(3)order by子句
PageResult.java
package com.rk.core.entity;
import java.util.ArrayList;
import java.util.List;
public class PageResult {
//总记录数
private long totalCount;
//当前页号
private int pageNo;
//总页数
private int totalPageCount;
//页大小
private int pageSize;
//列表记录
private List items;
//避免分页过大或过小
public static final int MAX_PAGE_SIZE = 100;
public static final int MIN_PAGE_SIZE = 3;
public PageResult(long totalCount, int totalPageCount,int pageSize, int pageNo, List items) {
this.totalCount = totalCount;
this.totalPageCount = totalPageCount;
this.pageSize = pageSize;
this.pageNo = pageNo;
this.items = items;
}
public long getTotalCount() {
return totalCount;
}
public void setTotalCount(long totalCount) {
this.totalCount = totalCount;
}
public int getPageNo() {
return pageNo;
}
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}
public int getTotalPageCount() {
return totalPageCount;
}
public void setTotalPageCount(int totalPageCount) {
this.totalPageCount = totalPageCount;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public List getItems() {
return items;
}
public void setItems(List items) {
this.items = items;
}
}
对于PageResult的分析:
(1)总记录数totalCount (根据sql语句从数据库获得)
(2)每一页的大小pageSize (一般由前台指定)
(3)由(1)和(2)得出总的页数totalPageCount (计算得出)
(4)判断当前页pageNo是否合理(是否小于1,是否大于totalPageCount);如果不合理,则进行校正
(5)取出当前页的数据items
2、使用QueryHelper
使用QueryHelper主要集中在dao层面上进行实现,而service层只是调用下一层(dao层)的功能。
2.1、Dao层
BaseDao.java
package com.rk.core.dao;
import java.io.Serializable;
import java.util.List;
import com.rk.core.entity.PageResult;
import com.rk.core.utils.QueryHelper;
public interface BaseDao<T> {
//新增
void save(T entity);
//更新
void update(T entity);
//根据id删除
void delete(Serializable id);
//根据id查找
T findById(Serializable id);
//查找列表
List<T> findAll();
//条件查询实体列表
List<T> findList(String hql, List<Object> parameters);
//条件查询实体列表--查询助手queryHelper
List<T> findList(QueryHelper queryHelper);
//分页条件查询实体列表--查询助手queryHelper
PageResult getPageResult(QueryHelper queryHelper, int pageNo, int pageSize);
}
其中添加的方法有
//条件查询实体列表
List<T> findList(String hql, List<Object> parameters);
//条件查询实体列表--查询助手queryHelper
List<T> findList(QueryHelper queryHelper);
//分页条件查询实体列表--查询助手queryHelper
PageResult getPageResult(QueryHelper queryHelper, int pageNo, int pageSize);
BaseDaoImpl.java
package com.rk.core.dao.impl;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.rk.core.dao.BaseDao;
import com.rk.core.entity.PageResult;
import com.rk.core.utils.HibernateConfigurationUtils;
import com.rk.core.utils.QueryHelper;
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
private Class<T> clazz;
@SuppressWarnings("unchecked")
public BaseDaoImpl() {
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
Type[] args = pt.getActualTypeArguments();
this.clazz = (Class<T>) args[0];
}
public void save(T entity) {
getHibernateTemplate().save(entity);
}
public void update(T entity) {
getHibernateTemplate().update(entity);
}
public void delete(Serializable id) {
String identifierPropertyName = HibernateConfigurationUtils.getIdentifierPropertyName(clazz);
Session session = getSession();
session.createQuery("delete from " + clazz.getSimpleName() + " where " + identifierPropertyName + "=?")
.setParameter(0, id).executeUpdate();
}
public T findById(Serializable id) {
return getHibernateTemplate().get(clazz, id);
}
@SuppressWarnings("unchecked")
public List<T> findAll() {
Session session = getSession();
Query query = session.createQuery("from " + clazz.getSimpleName());
return query.list();
}
public List<T> findList(String hql, List<Object> parameters) {
Query query = getSession().createQuery(hql);
if(parameters != null){
for(int i=0;i<parameters.size();i++){
query.setParameter(i, parameters.get(i));
}
}
return query.list();
}
public List<T> findList(QueryHelper queryHelper) {
Query query = getSession().createQuery(queryHelper.getQueryListHql());
List<Object> parameters = queryHelper.getParameters();
if(parameters != null){
for(int i=0;i<parameters.size();i++){
query.setParameter(i, parameters.get(i));
}
}
return query.list();
}
public PageResult getPageResult(QueryHelper queryHelper, int pageNo,int pageSize) {
//1、准备hql语句和参数
String hql = queryHelper.getQueryListHql();
String countHql = queryHelper.getQueryCountHql();
List<Object> parameters = queryHelper.getParameters();
//2、获取总的数据记录数
Query queryCount = getSession().createQuery(countHql);
if(parameters != null){
for(int i=0;i<parameters.size();i++){
queryCount.setParameter(i, parameters.get(i));
}
}
long totalCount = (Long) queryCount.uniqueResult();
//3、对页的大小进行约束
if(pageSize < PageResult.MIN_PAGE_SIZE) pageSize = PageResult.MIN_PAGE_SIZE;
if(pageSize > PageResult.MAX_PAGE_SIZE) pageSize = PageResult.MAX_PAGE_SIZE;
//4、求解总页数
int quotient = (int) (totalCount / pageSize);
int remainder = (int) (totalCount % pageSize);
int totalPageCount = remainder==0?quotient:(quotient+1);
//5、对当前页进行约束
if(pageNo < 1) pageNo = 1;
if(pageNo > totalPageCount) pageNo = totalPageCount;
//6、查询当前页的数据
Query query = getSession().createQuery(hql);
if(parameters != null){
for(int i=0;i<parameters.size();i++){
query.setParameter(i, parameters.get(i));
}
}
query.setFirstResult((pageNo-1)*pageSize);//设置数据起始索引号
query.setMaxResults(pageSize);
List list= query.list();
//7、返回分页数据
return new PageResult(totalCount,totalPageCount,pageSize,pageNo,list);
}
}
其中添加的方法有:
public List<T> findList(String hql, List<Object> parameters) {
Query query = getSession().createQuery(hql);
if(parameters != null){
for(int i=0;i<parameters.size();i++){
query.setParameter(i, parameters.get(i));
}
}
return query.list();
}
public List<T> findList(QueryHelper queryHelper) {
Query query = getSession().createQuery(queryHelper.getQueryListHql());
List<Object> parameters = queryHelper.getParameters();
if(parameters != null){
for(int i=0;i<parameters.size();i++){
query.setParameter(i, parameters.get(i));
}
}
return query.list();
}
public PageResult getPageResult(QueryHelper queryHelper, int pageNo,int pageSize) {
//1、准备hql语句和参数
String hql = queryHelper.getQueryListHql();
String countHql = queryHelper.getQueryCountHql();
List<Object> parameters = queryHelper.getParameters();
//2、获取总的数据记录数
Query queryCount = getSession().createQuery(countHql);
if(parameters != null){
for(int i=0;i<parameters.size();i++){
queryCount.setParameter(i, parameters.get(i));
}
}
long totalCount = (Long) queryCount.uniqueResult();
//3、对页的大小进行约束
if(pageSize < PageResult.MIN_PAGE_SIZE) pageSize = PageResult.MIN_PAGE_SIZE;
if(pageSize > PageResult.MAX_PAGE_SIZE) pageSize = PageResult.MAX_PAGE_SIZE;
//4、求解总页数
int quotient = (int) (totalCount / pageSize);
int remainder = (int) (totalCount % pageSize);
int totalPageCount = remainder==0?quotient:(quotient+1);
//5、对当前页进行约束
if(pageNo < 1) pageNo = 1;
if(pageNo > totalPageCount) pageNo = totalPageCount;
//6、查询当前页的数据
Query query = getSession().createQuery(hql);
if(parameters != null){
for(int i=0;i<parameters.size();i++){
query.setParameter(i, parameters.get(i));
}
}
query.setFirstResult((pageNo-1)*pageSize);//设置数据起始索引号
query.setMaxResults(pageSize);
List list= query.list();
//7、返回分页数据
return new PageResult(totalCount,totalPageCount,pageSize,pageNo,list);
}
2.2、Action层
BaseAction.java
package com.rk.core.action;
import com.opensymphony.xwork2.ActionSupport;
import com.rk.core.entity.PageResult;
public abstract class BaseAction extends ActionSupport {
protected String[] selectedRow;
protected PageResult pageResult;
protected int pageNo;
protected int pageSize;
protected String searchContent;
public String[] getSelectedRow() {
return selectedRow;
}
public void setSelectedRow(String[] selectedRow) {
this.selectedRow = selectedRow;
}
public PageResult getPageResult() {
return pageResult;
}
public void setPageResult(PageResult pageResult) {
this.pageResult = pageResult;
}
public int getPageNo() {
return pageNo;
}
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public String getSearchContent() {
return searchContent;
}
public void setSearchContent(String searchContent) {
this.searchContent = searchContent;
}
}
其中对查询条件支持的字段有:
protected String searchContent;
其中对分页查询支持的字段有:
protected PageResult pageResult;
protected int pageNo;
protected int pageSize;
InfoAction.java 主要关注listUI()方法,其它方法只是为了参考和理解
//列表页面
public String listUI(){
//加载分类集合
ActionContext.getContext().getContextMap().put("infoTypeMap", Info.INFO_TYPE_MAP);
//分页数据查询
QueryHelper queryHelper = new QueryHelper(Info.class, "i");
try {
if(StringUtils.isNotBlank(searchContent)){
searchContent = URLDecoder.decode(searchContent, "UTF-8");
queryHelper.addCondition("i.title like ?", "%"+searchContent+"%");
}
} catch (Exception e) {
e.printStackTrace();
}
queryHelper.addOrderByProperty("i.createTime", QueryHelper.ORDER_BY_DESC);
String hql = queryHelper.getQueryListHql();
pageResult = infoService.getPageResult(queryHelper, pageNo, pageSize);
return "listUI";
}
//跳转到新增页面
public String addUI(){
//加载分类集合
ActionContext.getContext().getContextMap().put("infoTypeMap", Info.INFO_TYPE_MAP);
info = new Info();
info.setCreateTime(new Timestamp(new Date().getTime())); // 是为了在页面中显示出当前时间
return "addUI";
}
//保存新增
public String add(){
if(info != null){
infoService.save(info);
}
return "list";
}
//跳转到编辑页面
public String editUI(){
//加载分类集合
ActionContext.getContext().getContextMap().put("infoTypeMap", Info.INFO_TYPE_MAP);
if(info != null && info.getInfoId() != null){
info = infoService.findById(info.getInfoId());
}
return "editUI";
}
//保存编辑
public String edit(){
if(info != null){
infoService.update(info);
}
return "list";
}
//删除
public String delete(){
if(info != null && info.getInfoId() != null){
infoService.delete(info.getInfoId());
}
return "list";
}
//批量删除
public String deleteSelected(){
if(selectedRow != null){
for(String id : selectedRow){
infoService.delete(id);
}
}
return "list";
}
其中,searchContent/pageNo/pageSize/pageResult变量继承自父类(BaseAction)。
除了实现条件查询(分页查询)之外,还要在进行“删除和编辑”操作时,需要记录“查询关键字”、“页码”。而新增操作,则不需要记住原来的“查询关键字”和“页码”,因为我们进行添加操作后,想看到的就是自己新添加的对象,而不是原来查询条件下记录。
在struts-tax.xml中,action是进行如下映射的:
<!-- InfoAction -->
<action name="info_*" class="infoAction" method="{1}">
<result name="{1}">/WEB-INF/jsp/tax/info/{1}.jsp</result>
<result name="list" type="redirectAction">
<param name="actionName">info_listUI</param>
<param name="searchContent">${searchContent}</param>
<param name="pageNo">${pageNo}</param>
<param name="encode">true</param>
</result>
</action>
此处对searchContent内容进行Url encode的转换,因为在listUI()方法代码中,
searchContent = URLDecoder.decode(searchContent, "UTF-8");
对于URLEncoder和URLDecoder的一个小测试
输出
UrlEncoder的源码
|
3、JSP页面
3.1、pageNavigator.jsp
在WebRoot/common目录下
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<div class="c_pate" >
<s:if test="pageResult.totalCount > 0">
<table width="100%" class="pageDown" border="0" cellspacing="0" cellpadding="0">
<tr>
<td align="right">
总共<s:property value="pageResult.totalCount"/>条记录,
当前第 <s:property value="pageResult.pageNo"/> 页,
共<s:property value="pageResult.totalPageCount"/> 页
<s:if test="pageResult.pageNo > 1">
<a href="javascript:doGoPage(<s:property value="pageResult.pageNo-1"/>)">上一页</a>
</s:if>
<s:else>
<a href="javascript:;">上一页</a>
</s:else>
<s:if test="pageResult.pageNo < pageResult.totalPageCount">
<a href="javascript:doGoPage(<s:property value="pageResult.pageNo+1"/>)">下一页</a>
</s:if>
<s:else>
<a href="javascript:;">下一页</a>
</s:else>
到 <input id="pageNo" name="pageNo" type="text" onkeypress="if(event.keyCode == 13){doGoPage(this.value);}" min="1"
max="<s:property value="pageResult.totalPageCount"/>" value="<s:property value="pageResult.pageNo"/>" />
</td>
</tr>
</table>
</s:if>
<s:else>
暂无数据!
</s:else>
</div>
<script type="text/javascript">
//翻页
function doGoPage(pageNum){
document.getElementById("pageNo").value = pageNum;
document.forms[0].action = list_url;
document.forms[0].submit();
}
//搜索
function doSearch(){
//重置页号
$('#pageNo').val(1);
document.forms[0].action = list_url;
document.forms[0].submit();
}
</script>
注意:在这最后一段Javascript中引用了一个list_url变量,它需要在主页面(listUI.jsp)内提供它的值。
3.2、listUI.jsp
<%@page import="org.apache.struts2.components.Include"%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<%@include file="/common/header.jsp"%>
<title>信息发布管理</title>
<script type="text/javascript">
//全选、全反选
function doSelectAll(){
// jquery 1.6 前
//$("input[name=selectedRow]").attr("checked", $("#selAll").is(":checked"));
//prop jquery 1.6+建议使用
$("input[name=selectedRow]").prop("checked", $("#selAll").is(":checked"));
}
//新增
function doAdd(){
document.forms[0].action = "${basePath}/tax/info_addUI.action";
document.forms[0].submit();
}
//编辑
function doEdit(id){
document.forms[0].action = "${basePath}/tax/info_editUI.action?info.infoId="+id;
document.forms[0].submit();
}
//删除
function doDelete(id){
document.forms[0].action = "${basePath}/tax/info_delete.action?info.infoId="+id;
document.forms[0].submit();
}
//批量删除
function doDeleteAll(){
document.forms[0].action = "${basePath}/tax/info_deleteSelected.action";
document.forms[0].submit();
}
//异步发布信息,信息的id及将要改成的信息状态
function doPublic(infoId, state){
//1、更新信息状态
$.ajax({
url:"${basePath}/tax/info_publicInfo.action",
data:{"info.infoId":infoId,"info.state":state},
type:"post",
success:function(msg){
//2、更新状态栏、操作拦的显示值
if("更新状态成功" == msg){
if(state == 1){//说明信息状态已经被改成 发布,状态栏显示 发布,操作栏显示 停用
$('#show_'+infoId).html("发布");
$('#oper_'+infoId).html('<a href="javascript:doPublic(\''+infoId+'\',0)">停用</a>');
}
else{
$('#show_'+infoId).html("停用");
$('#oper_'+infoId).html('<a href="javascript:doPublic(\''+infoId+'\',1)">发布</a>');
}
}
else{
alert("更新信息状态失败!");
}
},
error:function(){
alert("更新信息状态失败!");
}
});
}
var list_url = "${basePath}/tax/info_listUI.action";
</script>
</head>
<body class="rightBody">
<form name="form1" action="" method="post">
<div class="p_d_1">
<div class="p_d_1_1">
<div class="content_info">
<div class="c_crumbs"><div><b></b><strong>信息发布管理</strong></div> </div>
<div class="search_art">
<li>
信息标题:<s:textfield name="searchContent" cssClass="s_text" id="searchContent" cssStyle="width:160px;"/>
</li>
<li><input type="button" class="s_button" value="搜 索" onclick="doSearch()"/></li>
<li >
<input type="button" value="新增" class="s_button" onclick="doAdd()"/>
<input type="button" value="删除" class="s_button" onclick="doDeleteAll()"/>
</li>
</div>
<div class="t_list" >
<table width="100%" border="0">
<tr class="t_tit">
<td width="30" align="center"><input type="checkbox" id="selAll" onclick="doSelectAll()" /></td>
<td align="center">信息标题</td>
<td width="120" align="center">信息分类</td>
<td width="120" align="center">创建人</td>
<td width="140" align="center">创建时间</td>
<td width="80" align="center">状态</td>
<td width="120" align="center">操作</td>
</tr>
<s:iterator value="pageResult.items" status="st">
<tr <s:if test="#st.odd"> bgcolor="f8f8f8" </s:if> >
<td align="center"><input type="checkbox" name="selectedRow" value="<s:property value='infoId'/>"/></td>
<td align="center"><s:property value="title"/></td>
<td align="center">
<s:property value="#infoTypeMap[type]"/>
</td>
<td align="center"><s:property value="creator"/></td>
<td align="center"><s:date name="createTime" format="yyyy-MM-dd HH:mm"/></td>
<td id="show_<s:property value='infoId'/>" align="center"><s:property value="state==1?'发布':'停用'"/></td>
<td align="center">
<span id="oper_<s:property value="infoId"/>">
<s:if test="state==1">
<a href="javascript:doPublic('<s:property value="infoId" />',0)">停用</a>
</s:if>
<s:else>
<a href="javascript:doPublic('<s:property value="infoId"/>',1)">发布</a>
</s:else>
</span>
<a href="javascript:doEdit('<s:property value='infoId'/>')">编辑</a>
<a href="javascript:doDelete('<s:property value='infoId'/>')">删除</a>
</td>
</tr>
</s:iterator>
</table>
</div>
</div>
<%@include file="/common/pageNavigator.jsp" %>
</div>
</div>
</form>
</body>
</html>
知识点(1):在点击搜索的时候,要将页码设置为1
function doSearch(){
//重置页号
$('#pageNo').val(1);
document.forms[0].action = list_url;
document.forms[0].submit();
}
知识点(2):现在获取的显示数据不再是List对象,而是PageResult对象
<s:iterator value="pageResult.items" status="st">
知识点(3):为了引入通用的pageNavigator.jsp,需要定义一个list_url变量
var list_url = "${basePath}/tax/info_listUI.action";
引入页面
<%@include file="/common/pageNavigator.jsp" %>
3.3、editUI.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<%@include file="/common/header.jsp"%>
<title>信息发布管理</title>
<script type="text/javascript" src="${basePath}/js/ueditor/ueditor.config.js"></script>
<script type="text/javascript" src="${basePath}/js/ueditor/ueditor.all.js"></script>
<script type="text/javascript" src="${basePath}/js/ueditor/lang/zh-cn/zh-cn.js"></script>
<script>
window.UEDITOR_HOME_URL = "${basePath}/js/ueditor";
window.onload = function(){
var ue = UE.getEditor("editor");
}
</script>
</head>
<body class="rightBody">
<form id="form" name="form" action="${basePath}/tax/info_edit.action" method="post" enctype="multipart/form-data">
<div class="p_d_1">
<div class="p_d_1_1">
<div class="content_info">
<div class="c_crumbs"><div><b></b><strong>信息发布管理</strong> - 修改信息</div></div>
<div class="tableH2">修改信息</div>
<table id="baseInfo" width="100%" align="center" class="list" border="0" cellpadding="0" cellspacing="0" >
<tr>
<td class="tdBg" width="200px">信息分类:</td>
<td><s:select name="info.type" list="#infoTypeMap"/></td>
<td class="tdBg" width="200px">来源:</td>
<td><s:textfield name="info.source"/></td>
</tr>
<tr>
<td class="tdBg" width="200px">信息标题:</td>
<td colspan="3"><s:textfield name="info.title" cssStyle="width:90%"/></td>
</tr>
<tr>
<td class="tdBg" width="200px">信息内容:</td>
<td colspan="3"><s:textarea id="editor" name="info.content" cssStyle="width:90%;height:160px;" /></td>
</tr>
<tr>
<td class="tdBg" width="200px">备注:</td>
<td colspan="3"><s:textarea name="info.memo" cols="90" rows="3"/></td>
</tr>
<tr>
<td class="tdBg" width="200px">创建人:</td>
<td>
<s:property value="info.creator"/>
<s:hidden name="info.creator"/>
</td>
<td class="tdBg" width="200px">创建时间:</td>
<td>
<s:date name="info.createTime" format="yyyy-MM-dd HH:ss"/>
<s:hidden name="info.createTime"/>
</td>
</tr>
</table>
<!-- 当前信息的id和状态 -->
<s:hidden name="info.infoId"/>
<s:hidden name="info.state"/>
<!-- 暂存查询条件值 -->
<s:hidden name="searchContent"/>
<s:hidden name="pageNo"/>
<div class="tc mt20">
<input type="submit" class="btnB2" value="保存" />
<input type="button" onclick="javascript:history.go(-1)" class="btnB2" value="返回" />
</div>
</div></div></div>
</form>
</body>
</html>
知识点(1):为了保存查询的关键字和分页,将相应信息隐藏在编辑页面
<!-- 暂存查询条件值 -->
<s:hidden name="searchContent"/>
<s:hidden name="pageNo"/>
关于“SSH如何实现条件查询和分页查询”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。