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

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

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

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

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

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

例子:
[sql]  view plain copy
  1. FROM Info   
  2. WHERE title like ? and state = ?   
  3. order by createTime,state  

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

BaseDaoImpl实现类中添加实现方法:
[java]  view plain copy
  1. @Override  
  2. public List<T> findObjects(String hql,List<Object> parameters) {  
  3.     Query query=getSession().createQuery(hql);  
  4.     //添加查询条件  
  5.     if(parameters!=null){  
  6.         for (int i = 0; i < parameters.size(); i++) {  
  7.             query.setParameter(i, parameters.get(i));  
  8.         }  
  9.     }  
  10.     return query.list();  
  11. }  

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

BaseServiceImpl实现类中添加实现方法:
[java]  view plain copy
  1. @Override  
  2. public List<T> findObjects(String hql, List<Object> parameters) {  
  3.     return baseDao.findObjects(hql, parameters);  
  4. }  

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

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

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


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


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


因为我们可能还有多种查询条件,所以我们要对listUI方法进行修改,使之能够接受更多的参数去查询:
[java]  view plain copy
  1. //列表页面  
  2. public String listUI() throws Exception{  
  3.     try {  
  4.         //加载分类集合  
  5.         ActionContext.getContext().getContextMap().put("infoTypeMap", Info.INFO_TYPE_MAP);  
  6.         String hql="FROM Info i";  
  7.         List<Object> parameters=new ArrayList<Object>();  
  8.         if(info != null){  
  9.             if(StringUtils.isNotBlank(info.getTitle())){  
  10.                 hql+=" WHERE i.title like ?";  
  11.                 //加“%”进行模糊查询  
  12.                 parameters.add("%"+info.getTitle()+"%");  
  13.             }  
  14.             if(StringUtils.isNotBlank(info.getState())){  
  15.                 hql+=" AND i.state = ?";  
  16.                 //加“%”进行模糊查询  
  17.                 parameters.add("%"+info.getState()+"%");  
  18.             }  
  19.         }  
  20.         //根据创建时间降序排序  
  21.         hql+=" ORDER BY i.createTime DESC";  
  22.         infoList=infoService.findObjects(hql,parameters);  
  23.     } catch (Exception e) {  
  24.         throw new Exception(e.getMessage());  
  25.     }  
  26.     return "listUI";  
  27. }  

但是大家是不是感觉代码有些冗余?我们应该把像拼接hql语句这种容易处出错误且重复率极高的代码封装成一个工具类。
我们这里把hql语句的条件拼接封装成了一个工具类,名叫"QueryHelper":
[java]  view plain copy
  1. package cn.edu.hpu.tax.core.util;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. public class QueryHelper {  
  7.       
  8.     //from子句  
  9.     private String fromClause="";  
  10.     //where子句  
  11.     private String whereClause="";  
  12.     //oeder by子句  
  13.     private String orderByClause="";  
  14.       
  15.     private List<Object> parameters;  
  16.     //排序属性  
  17.     public static String ORDER_BY_DESC="DESC";//降序  
  18.     public static String ORDER_BY_ASC="ASC";//升序  
  19.       
  20.   
  21.   
  22.     /** 
  23.      * 构造from子句 
  24.      * @param clazz实体类 
  25.      * @param alias实体类对应的别名 
  26.      * */  
  27.     public QueryHelper(Class clazz,String alias){  
  28.         fromClause="FROM "+clazz.getSimpleName()+" "+alias;  
  29.     }  
  30.     /** 
  31.      * 构造where子句 
  32.      * @param condition查询条件语句:例如i.title like ? 
  33.      * @param params 查询条件语句中?对应的查询条件值,例如:%标题% 
  34.      * */  
  35.     public void addCondition(String condition,Object... params){  
  36.         if(whereClause.length()>1){//非第一个查询条件  
  37.             whereClause+=" AND "+condition;  
  38.         }else{//第一个查询条件  
  39.             whereClause+=" WHERE "+condition;  
  40.         }  
  41.           
  42.           
  43.         //设置查询条件值到查询条件值集合中  
  44.         if(parameters == null){  
  45.             parameters=new ArrayList<Object>();  
  46.         }  
  47.         if(params != null){  
  48.             for(Object param:params){  
  49.                 parameters.add(param);  
  50.             }  
  51.         }  
  52.     }  
  53.       
  54.     /** 
  55.      * 构造order by子句 
  56.      * @param property 查询条件语句:例如: 
  57.      * @param order 
  58.      * */  
  59.     public void addOrderByProperty(String property,String order){  
  60.         if(orderByClause.length()>1){//非第一个排序属性  
  61.             orderByClause+=","+property+" "+order;  
  62.         }else{//第一个排序属性  
  63.             orderByClause+=" ORDER BY "+property +" "+order;  
  64.         }  
  65.     }  
  66.       
  67.     //查询hql语句  
  68.     public String getQueryListHql(){  
  69.         return fromClause+whereClause+orderByClause;  
  70.     }  
  71.     //查询hql语句中?对应的查询条件集合  
  72.     public List<Object> getParameters(){  
  73.         return parameters;  
  74.     }  
  75. }  

我们在我们刚刚的listUI方法中使用这个工具类:
[java]  view plain copy
  1. //列表页面  
  2. public String listUI() throws Exception{  
  3.     try {  
  4.         //加载分类集合  
  5.         ActionContext.getContext().getContextMap().put("infoTypeMap", Info.INFO_TYPE_MAP);  
  6.         QueryHelper queryHelper=new QueryHelper(Info.class,"i");  
  7.         if(info != null){  
  8.             if(StringUtils.isNotBlank(info.getTitle())){  
  9.                 queryHelper.addCondition("i.title like ?""%"+info.getTitle()+"%");  
  10.             }  
  11.             queryHelper.addCondition("i.state = ?""1");  
  12.         }  
  13.         //根据创建时间降序排序  
  14.         queryHelper.addOrderByProperty("i.createTime", queryHelper.ORDER_BY_DESC);  
  15.         infoList=infoService.findObjects(queryHelper);  
  16.     } catch (Exception e) {  
  17.         throw new Exception(e.getMessage());  
  18.     }  
  19.     return "listUI";  
  20. }  

可以看到我们的findObjects现在只接收queryHelper这一个参数了,我们在BaseService中再添加一个只包含queryHelper参数的findObjects方法。
[java]  view plain copy
  1. package cn.edu.hpu.tax.core.service;  
  2.   
  3. import java.io.Serializable;  
  4. import java.util.List;  
  5.   
  6. import cn.edu.hpu.tax.core.util.QueryHelper;  
  7. import cn.edu.hpu.tax.info.entity.Info;  
  8.   
  9. public interface BaseService<T> {  
  10.       
  11.     //新增  
  12.     public void save(T entity);  
  13.     //更新  
  14.     public void update(T enetity);  
  15.     //根据id删除  
  16.     public void delete(Serializable id);  
  17.     //根据id查找  
  18.     public T findObjectById(Serializable id);  
  19.     //查找列表  
  20.     public List<T> findObjects();  
  21.     //条件查询  
  22.     @Deprecated //不推荐使用  
  23.     public List<T> findObjects(String hql, List<Object> parameters);  
  24.     //使用工具类的条件查询  
  25.     public List<T> findObjects(QueryHelper queryHelper);  
  26. }  

BaseServiceImpl中实现这个方法:
[java]  view plain copy
  1. @Override  
  2. public List<T> findObjects(QueryHelper queryHelper) {  
  3.     // TODO Auto-generated method stub  
  4.     return baseDao.findObjects(queryHelper);  
  5. }  

然后我们在Dao中也实现这个方法:
[java]  view plain copy
  1. package cn.edu.hpu.tax.core.dao;  
  2.   
  3. import java.io.Serializable;  
  4. import java.util.List;  
  5.   
  6. import cn.edu.hpu.tax.core.util.QueryHelper;  
  7. import cn.edu.hpu.tax.info.entity.Info;  
  8.   
  9. public interface BaseDao<T> {  
  10.       
  11.     //新增  
  12.     public void save(T entity);  
  13.     //更新  
  14.     public void update(T enetity);  
  15.     //根据id删除  
  16.     public void delete(Serializable id);  
  17.     //根据id查找  
  18.     public T findObjectById(Serializable id);  
  19.     //查找列表  
  20.     public List<T> findObjects();  
  21.     //条件查询  
  22.     public List<T> findObjects(String hql, List<Object> parameters);  
  23.     //使用工具类的条件查询  
  24.     public List<T> findObjects(QueryHelper queryHelper);  
  25. }  

BaseDaoImpl中实现这个方法:
[java]  view plain copy
  1. @Override  
  2. public List<T> findObjects(QueryHelper queryHelper) {  
  3.     Query query=getSession().createQuery(queryHelper.getQueryListHql());  
  4.     List<Object> parameters=queryHelper.getParameters();  
  5.     //添加查询条件  
  6.     if(parameters!=null){  
  7.         for (int i = 0; i < parameters.size(); i++) {  
  8.             query.setParameter(i, parameters.get(i));  
  9.         }  
  10.     }  
  11.     return query.list();  
  12. }  

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值