【SSH项目实战】国税协同平台-24.条件查询分析与实现

简介:
我们之前做好了信息发布管理这一块的功能

这次我们就以这个模块为例,去为其添加查询和分页功能。

我们先从查询功能做起:
条件查询(QueryHelper):

1、查询条件语句hql:
from 子句:必定出现;而且只出现一次
where 子句:可选;但关键字where 出现一次;可添加多个查询条件
order by子句:可选;但关键字order by 出现一次;可添加多个排序属性

2、查询条件值集合:
出现时机:在添加查询条件的时候,?对应的查询条件值

例子:
FROM Info 
WHERE title like ? and state = ? 
order by createTime,state

于是我们为了满足以后所有拥有查询功能的模块来编写查询类,我们在BaseDao(接口和实现类)中添加下面方法:
BaseDao接口中添加
//条件查询
public List<T> findObjects(String hql, List<Object> parameters);

BaseDaoImpl实现类中添加实现方法:
@Override
public List<T> findObjects(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();
}

然后我们在基础Service层中引用它,我们在BaseService(接口和实现类)中添加下面方法:
BaseService接口中添加
//条件查询
public List<T> findObjects(String hql, List<Object> parameters);

BaseServiceImpl实现类中添加实现方法:
@Override
public List<T> findObjects(String hql, List<Object> parameters) {
	return baseDao.findObjects(hql, parameters);
}

然后我们要修改我们的信息发布的Action中的listUI方法,因为我们一旦添加了分类查询方法,必然需要看看跳转到此界面是查询所有还是按条件查询,也就是判断一下有无条件值的存在,如果存在,说明用户是要获取查询后的列表,我们根据查询条件组织hql语句进行查询:
//列表页面
public String listUI() throws Exception{
	try {
		//加载分类集合
		ActionContext.getContext().getContextMap().put("infoTypeMap", Info.INFO_TYPE_MAP);
		String hql="FROM Info i ";
		List<Object> parameters=new ArrayList<Object>();
		if(info != null){
			if(StringUtils.isNotBlank(info.getTitle())){
				hql+="WHERE i.title like ?";
				//加“%”进行模糊查询
				parameters.add("%"+info.getTitle()+"%");
			}
		}
		//根据创建时间降序排序
		hql+="ORDER BY i.createTime DESC";
		infoList=infoService.findObjects(hql,parameters);
	} catch (Exception e) {
		throw new Exception(e.getMessage());
	}
	return "listUI";
}

在信息发布管理列表的jsp界面,我们点击“搜索”按钮时执行的是的js方法:
 <li>
 信息标题:<s:textfield name="info.title" cssClass="s_text" id="infoTitle"  cssStyle="width:160px;"/>
 </li>
 <li><input type="button" class="s_button" value="搜 索" onclick="doSearch()"/></li>

我们来编写doSearch()这个方法:
function doSearch(){
	document.forms[0].action = "${basePath}tax/info_listUI.action";
 		document.forms[0].submit();
}


我们测试一下:
我们一共有“图片上传测试”和“测试1”这两个文章,我们首先搜索“图片”关键字,然后出现如下结果:


然后我们搜索“测试”关键字,发现成功得到相关的文章:


因为我们可能还有多种查询条件,所以我们要对listUI方法进行修改,使之能够接受更多的参数去查询:
//列表页面
public String listUI() throws Exception{
	try {
		//加载分类集合
		ActionContext.getContext().getContextMap().put("infoTypeMap", Info.INFO_TYPE_MAP);
		String hql="FROM Info i";
		List<Object> parameters=new ArrayList<Object>();
		if(info != null){
			if(StringUtils.isNotBlank(info.getTitle())){
				hql+=" WHERE i.title like ?";
				//加“%”进行模糊查询
				parameters.add("%"+info.getTitle()+"%");
			}
			if(StringUtils.isNotBlank(info.getState())){
				hql+=" AND i.state = ?";
				//加“%”进行模糊查询
				parameters.add("%"+info.getState()+"%");
			}
		}
		//根据创建时间降序排序
		hql+=" ORDER BY i.createTime DESC";
		infoList=infoService.findObjects(hql,parameters);
	} catch (Exception e) {
		throw new Exception(e.getMessage());
	}
	return "listUI";
}

但是大家是不是感觉代码有些冗余?我们应该把像拼接hql语句这种容易处出错误且重复率极高的代码封装成一个工具类。
我们这里把hql语句的条件拼接封装成了一个工具类,名叫"QueryHelper":
package cn.edu.hpu.tax.core.util;

import java.util.ArrayList;
import java.util.List;

public class QueryHelper {
	
	//from子句
	private String fromClause="";
	//where子句
	private String whereClause="";
	//oeder by子句
	private String orderByClause="";
	
	private List<Object> 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<Object>();
		}
		if(params != null){
			for(Object param:params){
				parameters.add(param);
			}
		}
	}
	
	/**
	 * 构造order by子句
	 * @param property 查询条件语句:例如:
	 * @param order
	 * */
	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 List<Object> getParameters(){
		return parameters;
	}
}

我们在我们刚刚的listUI方法中使用这个工具类:
//列表页面
public String listUI() throws Exception{
	try {
		//加载分类集合
		ActionContext.getContext().getContextMap().put("infoTypeMap", Info.INFO_TYPE_MAP);
		QueryHelper queryHelper=new QueryHelper(Info.class,"i");
		if(info != null){
			if(StringUtils.isNotBlank(info.getTitle())){
				queryHelper.addCondition("i.title like ?", "%"+info.getTitle()+"%");
			}
			queryHelper.addCondition("i.state = ?", "1");
		}
		//根据创建时间降序排序
		queryHelper.addOrderByProperty("i.createTime", queryHelper.ORDER_BY_DESC);
		infoList=infoService.findObjects(queryHelper);
	} catch (Exception e) {
		throw new Exception(e.getMessage());
	}
	return "listUI";
}

可以看到我们的findObjects现在只接收queryHelper这一个参数了,我们在BaseService中再添加一个只包含queryHelper参数的findObjects方法。
package cn.edu.hpu.tax.core.service;

import java.io.Serializable;
import java.util.List;

import cn.edu.hpu.tax.core.util.QueryHelper;
import cn.edu.hpu.tax.info.entity.Info;

public interface BaseService<T> {
	
	//新增
	public void save(T entity);
	//更新
	public void update(T enetity);
	//根据id删除
	public void delete(Serializable id);
	//根据id查找
	public T findObjectById(Serializable id);
	//查找列表
	public List<T> findObjects();
	//条件查询
	@Deprecated //不推荐使用
	public List<T> findObjects(String hql, List<Object> parameters);
	//使用工具类的条件查询
	public List<T> findObjects(QueryHelper queryHelper);
}

BaseServiceImpl中实现这个方法:
@Override
public List<T> findObjects(QueryHelper queryHelper) {
	// TODO Auto-generated method stub
	return baseDao.findObjects(queryHelper);
}

然后我们在Dao中也实现这个方法:
package cn.edu.hpu.tax.core.dao;

import java.io.Serializable;
import java.util.List;

import cn.edu.hpu.tax.core.util.QueryHelper;
import cn.edu.hpu.tax.info.entity.Info;

public interface BaseDao<T> {
	
	//新增
	public void save(T entity);
	//更新
	public void update(T enetity);
	//根据id删除
	public void delete(Serializable id);
	//根据id查找
	public T findObjectById(Serializable id);
	//查找列表
	public List<T> findObjects();
	//条件查询
	public List<T> findObjects(String hql, List<Object> parameters);
	//使用工具类的条件查询
	public List<T> findObjects(QueryHelper queryHelper);
}

BaseDaoImpl中实现这个方法:
@Override
public List<T> findObjects(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();
}

然后我们测试一下,搜索“测试”关键字,结果:

证明我们的分类助手工具类编写没有问题,至此我们的分类查询暂时编写完毕。

转载请注明出处:http://blog.csdn.net/acmman/article/details/49887293

相关文章
|
1月前
|
网络安全
ssh根据姓名查询的时候报错java.lang.IndexOutOfBoundsException: Remember that
ssh根据姓名查询的时候报错java.lang.IndexOutOfBoundsException: Remember that
|
1月前
|
网络安全
ssh根据姓名查询的时候报错java.lang.IndexOutOfBoundsException: Remember that ordinal parameters are 1-based!
ssh根据姓名查询的时候报错java.lang.IndexOutOfBoundsException: Remember that ordinal parameters are 1-based!
|
11月前
|
网络协议 算法 数据挖掘
抓包分析ssh远程主机为何变慢了?
在使用spug自动化部署程序的时候,会使用ssh协议远程执行脚本,但是ssh那一步会耗时比较旧,网上的解决方案五花八门. 问题可能可以解决,但是背后原理并不清楚,借此机会抓包将此问题彻底消化.
115 0
|
分布式计算 安全 Ubuntu
ssh 配置:在 Linux 中 ssh 配置无密码登陆完整步骤以及易错点分析
ssh 配置:在 Linux 中 ssh 配置无密码登陆完整步骤以及易错点分析
434 1
ssh 配置:在 Linux 中 ssh 配置无密码登陆完整步骤以及易错点分析
|
Java 数据库连接 网络安全
ssh框架整合时的延迟加载问题(no session问题)的分析以及解决方案
ssh框架整合时的延迟加载问题(no session问题)的分析以及解决方案
74 0
ssh框架整合时的延迟加载问题(no session问题)的分析以及解决方案
|
SQL Java 数据库连接
SSH项目,hibernate的查询操作出错org.hibernate.hql.ast.QuerySyntaxException
SSH项目,hibernate的查询操作出错org.hibernate.hql.ast.QuerySyntaxException
244 0
|
弹性计算 安全 算法
通过WireShark对SSH协议进行分析
该实验探讨了SSH的基于口令安全认证,主要关注SSH2的传输层协议和用户认证协议。实验中,客户端使用Termius,服务器端为运行Ubuntu的ECS,均基于SSH2。连接过程包括建立加密通道、用户密码加密传输及认证。通过抓包分析了SSH连接步骤,如版本协商、加密算法选择、公钥确认和Diffie-Hellman密钥交换。实验强调了基于口令认证的SSH在遭遇中间人攻击时的安全风险,提示用户需警惕服务器指纹的变化,防止MITM攻击。
2326 0
通过WireShark对SSH协议进行分析
|
弹性计算 Oracle 关系型数据库
NO.8 学会如何部署Oracle数据库、了解FTP机制、通过Squid代理上网、SSH密钥登录,最后学会故障分析,着重推荐“应用数据迁移网络异常案例分析”这篇
NO.8 本月我们首先了解一下新增的部分实用功能和如何部署Oracle数据库、了解FTP机制、通过Squid代理上网、SSH密钥登录,最后我们还是要学会故障分析,着重推荐“应用数据迁移网络异常案例分析”这篇。
2113 0