SSH如何实现条件查询和分页查询

这篇文章将为大家详细讲解有关SSH如何实现条件查询和分页查询,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

创新互联是专业的代县网站建设公司,代县接单;提供成都网站建设、成都网站设计,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行代县网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

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 parameters;
	//排序顺序
	public static String ORDER_BY_DESC = "DESC";//降序
	public static String ORDER_BY_ASC = "ASC";//升序
	
	/**
	 * 构造from子句
	 * @param clazz 实体类
	 * @param alias 实体类对应的别名
	 */
	public QueryHelper(Class clazz,String alias){
		fromClause = "FROM " + clazz.getSimpleName() + " " + alias;
	}
	
	/**
	 * 构造where子句
	 * @param condition 查询条件语句;例如:i.title like ?
	 * @param params 查询条件语句中对应的查询条件值;例如:%标题%
	 */
	public void addCondition(String condition, Object... params){
		if(whereClause.length() > 1){ //非第一个查询条件
			whereClause += " AND " + condition;
		}
		else{//第一个查询条件
			whereClause += " WHERE " + condition;
		}
		
		//设置 查询条件值 到 查询条件值集合 中
		if(parameters == null){
			parameters = new ArrayList();
		}
		if(params != null){
			for(Object param : params){
				parameters.add(param);
			}
		}
	}
	
	/**
	 * 构造order by子句
	 * @param property 排序属性;例如:i.createTime
	 * @param order 排序顺序;例如:DESC 或者 ASC
	 */
	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 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 {
	//新增
	void save(T entity);
	//更新
	void update(T entity);
	//根据id删除
	void delete(Serializable id);
	//根据id查找
	T findById(Serializable id);
	//查找列表
	List findAll();
	//条件查询实体列表
	List findList(String hql, List parameters);
	//条件查询实体列表--查询助手queryHelper
	List findList(QueryHelper queryHelper);
	//分页条件查询实体列表--查询助手queryHelper
	PageResult getPageResult(QueryHelper queryHelper, int pageNo, int pageSize);
}

其中添加的方法有

	//条件查询实体列表
	List findList(String hql, List parameters);
	//条件查询实体列表--查询助手queryHelper
	List 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 extends HibernateDaoSupport implements BaseDao {

	private Class clazz;
	
	@SuppressWarnings("unchecked")
	public BaseDaoImpl() {
		ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
		Type[] args = pt.getActualTypeArguments();
		this.clazz = (Class) 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 findAll() {
		Session session = getSession();
		Query query = session.createQuery("from " + clazz.getSimpleName());
		return query.list();
	}

	public List findList(String hql, List parameters) {
		Query query = getSession().createQuery(hql);
		if(parameters != null){
			for(int i=0;i findList(QueryHelper queryHelper) {
		Query query = getSession().createQuery(queryHelper.getQueryListHql());
		List parameters = queryHelper.getParameters();
		if(parameters != null){
			for(int i=0;i parameters = queryHelper.getParameters();
		//2、获取总的数据记录数
		Query queryCount = getSession().createQuery(countHql);
		if(parameters != null){
			for(int i=0;i 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

其中添加的方法有:

	public List findList(String hql, List parameters) {
		Query query = getSession().createQuery(hql);
		if(parameters != null){
			for(int i=0;i findList(QueryHelper queryHelper) {
		Query query = getSession().createQuery(queryHelper.getQueryListHql());
		List parameters = queryHelper.getParameters();
		if(parameters != null){
			for(int i=0;i parameters = queryHelper.getParameters();
		//2、获取总的数据记录数
		Query queryCount = getSession().createQuery(countHql);
		if(parameters != null){
			for(int i=0;i 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

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是进行如下映射的:

        
        
        	/WEB-INF/jsp/tax/info/{1}.jsp
        	
        		info_listUI
        		${searchContent}
        		${pageNo}
        		true
        	
        

此处对searchContent内容进行Url encode的转换,因为在listUI()方法代码中,

searchContent = URLDecoder.decode(searchContent, "UTF-8");

对于URLEncoder和URLDecoder的一个小测试

	@Test
	public void test() throws Exception{
		String str = "中国";
		String strEncode = URLEncoder.encode(str,"utf-8");
		String strDecode = URLDecoder.decode(strEncode, "utf-8");
		String strDecode2 = URLDecoder.decode(str, "utf-8");
		
		System.out.println(str);
		System.out.println(strEncode);
		System.out.println(strDecode);
		System.out.println(strDecode2);
	}

输出

中国
%E4%B8%AD%E5%9B%BD
中国
中国

UrlEncoder的源码

public class URLDecoder {

    // The platform default encoding
    static String dfltEncName = URLEncoder.dfltEncName;


    /**
     * Decodes a application/x-www-form-urlencoded string using a specific
     * encoding scheme.
     *
     * The supplied encoding is used to determine what characters 
     * are represented by any consecutive sequences of the form "%xy".
     * 
     * 
     * Note: The World Wide Web Consortium Recommendation states that
     * UTF-8 should be used. Not doing so may introduce incompatibilites.
     * 
     *
     * @param s the String to decode
     * @param enc   The name of a supported character encoding
     * @return the newly decoded String
     */
    public static String decode(String s, String enc)
        throws UnsupportedEncodingException{

        boolean needToChange = false;
        int numChars = s.length();
        StringBuffer sb = new StringBuffer(numChars > 500 ? numChars / 2 : numChars);
        int i = 0;

        if (enc.length() == 0) {
            throw new UnsupportedEncodingException ("URLDecoder: empty string enc parameter");
        }

        char c;
        byte[] bytes = null;
        while (i < numChars) {
            c = s.charAt(i);
            switch (c) {
            case '+':
                sb.append(' ');
                i++;
                needToChange = true;
                break;
            case '%':
                /*
                 * Starting with this instance of %, process all
                 * consecutive substrings of the form %xy. Each
                 * substring %xy will yield a byte. Convert all
                 * consecutive  bytes obtained this way to whatever
                 * character(s) they represent in the provided
                 * encoding.
                 */

                try {

                    // (numChars-i)/3 is an upper bound for the number
                    // of remaining bytes
                    if (bytes == null)
                        bytes = new byte[(numChars-i)/3];
                    int pos = 0;

                    while ( ((i+2) < numChars) &&
                            (c=='%')) {
                        int v = Integer.parseInt(s.substring(i+1,i+3),16);
                        if (v < 0)
                            throw new IllegalArgumentException("URLDecoder: Illegal hex characters in escape (%) pattern - negative value");
                        bytes[pos++] = (byte) v;
                        i+= 3;
                        if (i < numChars)
                            c = s.charAt(i);
                    }

                    // A trailing, incomplete byte encoding such as
                    // "%x" will cause an exception to be thrown

                    if ((i < numChars) && (c=='%'))
                        throw new IllegalArgumentException(
                         "URLDecoder: Incomplete trailing escape (%) pattern");

                    sb.append(new String(bytes, 0, pos, enc));
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException(
                    "URLDecoder: Illegal hex characters in escape (%) pattern - "
                    + e.getMessage());
                }
                needToChange = true;
                break;
            default:
                sb.append(c);
                i++;
                break;
            }
        }

        return (needToChange? sb.toString() : s);
    }
}

3、JSP页面

3.1、pageNavigator.jsp

在WebRoot/common目录下

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

	 0">
		
			
				
                	总共条记录,
                	当前第  页,
                 	共 页   
                     1">
                            )">上一页  
                    
                    
                    	上一页  
                            
                    
                            )">下一页
                    
                    
                    	下一页
                            
					到 " value="" />   
			    
			
		
	
	
		暂无数据!
	


	//翻页
	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();
	}

注意:在这最后一段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" %>


    <%@include file="/common/header.jsp"%>
    信息发布管理
    
      	//全选、全反选
		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('停用');
  						}
  						else{
  							$('#show_'+infoId).html("停用");
  							$('#oper_'+infoId).html('发布');
  						}
  					}
  					else{
  						alert("更新信息状态失败!");
  					}
  				},
  				error:function(){
  					alert("更新信息状态失败!");
  				}
  			});
  		}
        var list_url = "${basePath}/tax/info_listUI.action";

    



    
        
            
                
信息发布管理
                                       
  •                         信息标题:                     
  •                     
  •                                                                                                                                                                                                                                        信息标题                             信息分类                             创建人                             创建时间                             状态                             操作                                                                                bgcolor="f8f8f8"  >                                 "/>                                                                                                                                                                                                                                       " align="center">                                                                   ">                                                                   ',0)">停用                                                                                                    ',1)">发布                                                                                                       ')">编辑                                     ')">删除                                                                                                                                           <%@include file="/common/pageNavigator.jsp" %>              

    知识点(1):在点击搜索的时候,要将页码设置为1

            function doSearch(){
            	//重置页号
            	$('#pageNo').val(1);
            	document.forms[0].action = list_url;
            	document.forms[0].submit();
            }

    知识点(2):现在获取的显示数据不再是List对象,而是PageResult对象

    知识点(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" %>
    
    
        <%@include file="/common/header.jsp"%>
        信息发布管理
    	
    	
    	
        
    
    
    
        
            
                
        
    信息发布管理 - 修改信息
        修改信息                           信息分类:                          来源:                                            信息标题:                                            信息内容:                                            备注:                                            创建人:                                                                              创建时间:                                                                                                                                                 

    知识点(1):为了保存查询的关键字和分页,将相应信息隐藏在编辑页面

        
        
        

    关于“SSH如何实现条件查询和分页查询”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。


    文章题目:SSH如何实现条件查询和分页查询
    URL地址:http://scjbc.cn/article/gihijp.html