论坛首页 Java企业应用论坛

2年前的DynamicQueryTool如今的样子。

浏览 4348 次
该帖已经被评为良好帖
作者 正文
   发表时间:2009-03-31   最后修改:2009-03-31
2年前做了个小工具:DynamicQueryTool 。 当时做这个小工具的想法仅仅是为了解决项目中经常用到的“表单”查询的问题。根据用户选择的条件动态拼装SQL/HQL语句。

这两年不断的在项目中演进,已经相对完善成熟了许多,今天偶然看到坛子上还有人讨论DynamicQueryTool的问题让我很是惊讶,既然有人关注,我就把最新的queryTool版本拿出来,以及主要的改进也给大家说一下:
主要改进:

* 支持自定义函数:

  
protected static final QueryTool QT = new QueryTool(new FilterTag("ignore", "<", ">", "</", ">"));

	static {
		QT.addGlobaleDefinedExp("NULL", new AbstractBeanExp() {

			@Override
			protected boolean isVallid(Object arg0) {

				return arg0 == null;
			}
		});
		QT.addGlobaleDefinedExp("TRUE", new AbstractBeanExp() {

			@Override
			protected boolean isVallid(Object arg0) {

				return Boolean.TRUE.equals(arg0);
			}
		});
		QT.addGlobaleDefinedExp("FALSE", new AbstractBeanExp() {

			@Override
			protected boolean isVallid(Object arg0) {

				return Boolean.FALSE.equals(arg0);
			}
		});
		QT.addGlobaleDefinedExp("NOTEMPTY", new AbstractBeanExp() {

			@Override
			protected boolean isVallid(Object arg0) {
				Collection col = (Collection) arg0;
				return col != null && !col.isEmpty();
			}
		});
	}


* 对条件tag增加ognl写法的支持

    <NOTNULL:a.b.id> and o.test.id=? </NOTNULL:a.b.id>

* 支持直接从VO中获得参数
    <NOTEMPTY:idList> and o.test.id=:myId </NOTEMPTY:idList>

     其中: myId是vo的getter 属性。

* 对从VO直接生成DynamicQResult的支持更加完善


* 支持嵌套的tag

   <NOTNULL:a.id> <NOTNULL:b.id>  and a.b.id=:bId </NOTNULL:b.id> </NOTNULL;a.id>

   等价于:
   <NOTNULL:a.id&NOTNULL:b.id>  and a.b.id=:bId  </NOTNULL:a.id&NOTNULL:b.id>

* 支持参数的更改(常为了模糊查询以及日期比较)
   DynamicQResult dqr = QT.parse(CONDITION_HQL).changeParam(new Object[] { "title","address","fullName" }).to(new NewParamValue() {

			public Object newParamValue(Object arg0) {

				return "%" + Utils.escapeSQLLike(arg0 + "") + "%";
			}
		}).changeParam(new String[] { "publishEndTime","createDate" }).to(new NewParamValue() {

			public Object newParamValue(Object arg0) {

				return DateUtils.addDays((Date) arg0, 1);
			}
		}).setProperties(report).generate();





   发表时间:2009-03-31  
完整的例子如下所示:

/*
 * Copyright 2002-2007 tayoo company.
 */
package com.tayoo.service.invest;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import net.sf.querytool.DynamicQResult;
import net.sf.querytool.FilterTag;
import net.sf.querytool.NewParamValue;
import net.sf.querytool.beanexp.AbstractBeanExp;
import net.sf.querytool.provider.QueryTool;

import org.apache.commons.lang.time.DateUtils;
import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.util.Assert;

import com.tayoo.constants.Constants;
import com.tayoo.constants.InvestConstants;
import com.tayoo.domain.ThreadStore;
import com.tayoo.utils.Utils;

/**
 * 
 * @author wyx since 2009-3-31
 */
public class DynamicQueryService extends HibernateDaoSupport {

	// use the xml tag as the filterTag
	// use the xml tag as the filterTag
	protected static final QueryTool QT = new QueryTool(new FilterTag("ignore", "<", ">", "</", ">"));

	static {
		QT.addGlobaleDefinedExp("NULL", new AbstractBeanExp() {

			@Override
			protected boolean isVallid(Object arg0) {

				return arg0 == null;
			}
		});
		QT.addGlobaleDefinedExp("TRUE", new AbstractBeanExp() {

			@Override
			protected boolean isVallid(Object arg0) {

				return Boolean.TRUE.equals(arg0);
			}
		});
		QT.addGlobaleDefinedExp("FALSE", new AbstractBeanExp() {

			@Override
			protected boolean isVallid(Object arg0) {

				return Boolean.FALSE.equals(arg0);
			}
		});
		QT.addGlobaleDefinedExp("NOTEMPTY", new AbstractBeanExp() {

			@SuppressWarnings("unchecked")
			@Override
			protected boolean isVallid(Object arg0) {
				Collection col = (Collection) arg0;
				return col != null && !col.isEmpty();
			}
		});
	}

	@SuppressWarnings("unchecked")
	public List findInvestPartyRelationByReport(InvestReportQueryVo report, int pageNo, int pageSize) {
		String CONDITION_HQL = " from InvestFormTask t where 1=1  "
				+ " <NOTEMPTY:relIds> and  t.relation.id in (:relIds) </NOTEMPTY:relIds> "
				+ " <NOTEMPTYSTR:title> and t.relation.invest.title like :title</NOTEMPTYSTR:title>" // 排查标题
				+ "	<NOTNULL:publishBeginTime> and t.relation.parent.publishTime >= :publishBeginTime</NOTNULL:publishBeginTime> " // 排查发布日期时间段开始
				+ "	<NOTNULL:publishEndTime> and t.relation.parent.publishTime < :publishEndTime</NOTNULL:publishEndTime> " // 排查发布日期时间段结束
				+ " <NOTNULL:currOrgId> and t.relation.party.id = :currOrgId </NOTNULL:currOrgId> " // 自己上报
				+ " <NOTEMPTYSTR:mainOrgType> and t.relation.type = :mainOrgType </NOTEMPTYSTR:mainOrgType>"
				+ "<NOTEMPTYSTR:investType> and t.relation.invest.investType = :investType </NOTEMPTYSTR:investType>  "
				+ "<TRUE:monthReport> and t.year = :year and t.month = :month  </TRUE:monthReport>  "
				+ "<TRUE:localStatuses> and t.localStatus = :status </TRUE:localStatuses>"
				+ " <TRUE:superBacked> and t.status = :backedStatus  </TRUE:superBacked>"
				+ " <TRUE:superAudited> and t.status = :auditedStatus  </TRUE:superAudited>"
				+ " <TRUE:reported> and t.localStatus = :auditedStatus  </TRUE:reported>";
		DynamicQResult dqr = QT.parse(CONDITION_HQL).changeParam(new Object[] { "title" }).to(new NewParamValue() {

			public Object newParamValue(Object arg0) {

				return "%" + Utils.escapeSQLLike(arg0 + "") + "%";
			}
		}).changeParam(new String[] { "publishEndTime" }).to(new NewParamValue() {

			public Object newParamValue(Object arg0) {

				return DateUtils.addDays((Date) arg0, 1);
			}
		}).setProperties(report).generate();

		return this.findByDynamicQuery(dqr, pageNo, pageSize);
	}

	@SuppressWarnings("unchecked")
	protected List findByDynamicQuery(final DynamicQResult dqr, final int pageNo, final int pageSize) {
		Assert.notNull(dqr);
		Assert.isTrue(pageNo >= 1, "pageNo should start from 1");
		String hql = dqr.getQueryStr();
		Map<Object, Object> params = dqr.getParams();

		int startIndex = (pageNo - 1) * pageSize;
		Query query = createQuery(hql, params);
		List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
		return list;

	}

	@SuppressWarnings( { "unused", "unchecked" })
	protected Query createQuery(final String hql, final Map<Object, Object> params) {

		Query q = this.getSession().createQuery(hql);

		if (params != null) {
			for (Object paramKey : params.keySet()) {

				Object paramValue = params.get(paramKey);
				if (paramKey instanceof String) {
					if (paramValue instanceof List) {
						q.setParameterList((String) paramKey, (List) paramValue);
					} else {
						q.setParameter((String) paramKey, paramValue);
					}
				} else if (paramKey instanceof Integer)
					q.setParameter((Integer) paramKey - 1, paramValue);
				else
					throw new RuntimeException(" paramkey:" + paramKey + " should be integer or string type");

			}
		}

		return q;

	}

	public static class InvestReportQueryVo implements Serializable {

		private static final long serialVersionUID = -4023964071767191949L;

		private String title; // 标题

		private String status = InvestConstants.TASK_STATUS_WAIT_REPORT; // 任务状态

		private Date publishBeginTime; // 起始发布日期

		private Date publishEndTime; // 结束发布日期

		private Long orgId;

		private Integer year; // 月排查上报的年份

		private Integer month; // 月排查上报的月份

		private String investType;

		private List<Long> relIds;

		public List<Long> getRelIds() {
			return relIds;
		}

		public void setRelIds(List<Long> relIds) {
			this.relIds = relIds;
		}

		public String getInvestType() {
			return investType;
		}

		public void setInvestType(String investType) {
			this.investType = investType;
		}

		public Integer getYear() {
			return year;
		}

		public void setYear(Integer year) {
			this.year = year;
		}

		public Integer getMonth() {
			return month;
		}

		public void setMonth(Integer month) {
			this.month = month;
		}

		public Long getOrgId() {
			return orgId;
		}

		public void setOrgId(Long orgId) {
			this.orgId = orgId;
		}

		public String getTitle() {
			return title;
		}

		public void setTitle(String title) {
			this.title = title;
		}

		public String getStatus() {
			return status;
		}

		public void setStatus(String status) {
			this.status = status;
		}

		public Date getPublishBeginTime() {
			return publishBeginTime;
		}

		public void setPublishBeginTime(Date publishBeginTime) {
			this.publishBeginTime = publishBeginTime;
		}

		public Date getPublishEndTime() {
			return publishEndTime;
		}

		public void setPublishEndTime(Date publishEndTime) {
			this.publishEndTime = publishEndTime;
		}

		public String getMainOrgType() {
			return Constants.PARTY_MAIN_ORG;
		}

		public Long getCurrOrgId() {
			return ThreadStore.getCurrentUserOrgId();
		}

		public boolean isMonthReport() {
			return InvestConstants.INVEST_TYPE_MONTH.equals(this.getInvestType());
		}

		public boolean isLocalStatuses() {
			return "待上报".equals(this.status) || "待审核".equals(this.status) || "已退回".equals(this.status);
		}

		public boolean isSuperBacked() {
			return "上级退回".equals(this.status);
		}

		public boolean isSuperAudited() {
			return "上级审核通过".equals(this.status);
		}

		public boolean isReported() {
			return "已上报".equals(this.status);
		}

		public String getBackedStatus() {
			return InvestConstants.TASK_STATUS_BAKCED;
		}

		public String getAuditedStatus() {
			return InvestConstants.TASK_STATUS_AUDITED;
		}

	}

}


0 请登录后投票
   发表时间:2009-03-31  
批一下:notnull这些标签成对出现,得写两次,<notnull:xxx> xxx没有自动完成,输入浪费时间,
0 请登录后投票
   发表时间:2009-03-31  
nihongye 写道
批一下:notnull这些标签成对出现,得写两次,<notnull:xxx> xxx没有自动完成,输入浪费时间,


呵呵,当时是采用了类XML的写法, 写的时候是烦琐点,但是xml的标签写法,写的时候有点繁琐,但是看起来就比较清楚了,哪里开始,哪里结束都很清楚。

至于你说的自动完成,是啥回事?
0 请登录后投票
   发表时间:2009-03-31  
编辑器自动完成
0 请登录后投票
   发表时间:2009-03-31  
firebody 写道
2年前做了个小工具:DynamicQueryTool 。 当时做这个小工具的想法仅仅是为了解决项目中经常用到的“表单”查询的问题。根据用户选择的条件动态拼装SQL/HQL语句。

这两年不断的在项目中演进,已经相对完善成熟了许多,今天偶然看到坛子上还有人讨论DynamicQueryTool的问题让我很是惊讶,既然有人关注,我就把最新的queryTool版本拿出来,以及主要的改进也给大家说一下:
主要改进:

* 支持自定义函数:



看到楼主的工具,偶也想起来了当年也做了类似的工具。只不过,它的命运不怎么好了,项目组一直没有使用到Hibernate,所以工具就废掉了。

链接如下:

 

eXtremeComponents、Hibernate、Struts的分页改进之一

 

eXtremeComponents、Hibernate、Struts的分页改进之二

 

eXtremeComponents、Hibernate、Struts的分页改进之三 



 

 

0 请登录后投票
   发表时间:2010-01-05  
没有源码, 也没有项目地址啊?????....
0 请登录后投票
   发表时间:2010-01-05  
看起来好复杂
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics