`
qq1988627
  • 浏览: 107299 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

查询条件集中处理类

 
阅读更多
package zxc.utils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 主要用来完成条件的包装,通常是为页面上的数据查询服务.在数据查询的时候通常会有多个条件域,每个条件域又分为多种条件类型.
 * 通常需要把页面上的查询条件转换为后台的关系型数据库的查询条件比较零碎与繁琐,此类主要就是为了提供一种通用的转换方式.
 * 通常页面条件第一步会以字段的形式传到后台保存(可以把它们放到一个map中,或用一个javabean封装),将封装好的map或javabean
 * 传到业务层,进而传到dao层进行条件转换.这个类可以在action控制层,或者业务层,或者dao进行条件的转换,可以根据需要进行.通常
 * 我认为应该放在dao来进行转换,但是放到业务层我认为也可以.<br />
 * 这个类主要解决如下的几个问题:1.单个条件域各种条件形式;2.多个条件域之间的逻辑关系<br />
 * 需要考虑的几个因素:<br />
 * 1.对于一个条件域的类型,可能为:等于,大于,小于,大于等于,小于等于,不等于,like,in,not in,between and,等等;<br />
 * 2.对于多个条件域之间的逻辑关系可能为:逻辑与,逻辑或,逻辑非; <br />
 * 3.定制条件是用静态,还是用问号作为占位符; <br />
 * 4.多个条件域之间可能需要加括号的问题; <br />
 * 5.字段是否需要加一个表的别名前缀
 * 
 * @author KHT
 * 
 */
public class Condition {

	/**
	 * 添加一个字段条件,其它选项全部使用默认设置
	 * 
	 * @param fieldName 字段名称
	 * @param fieldValue 字段的值
	 * @return 添加字段条件片段后的条件对象
	 */
	public Condition addField(String fieldName, Object fieldValue) {
		this.addField(fieldName, fieldValue, this.conditionType, this.logicType, this.interrogation, this.prefix);
		return this;
	}

	/**
	 * 添加一系列具有相同选项的字段条件,这些条件用一个Map来进行包装
	 * 
	 * @param keyValue 一个封装条件的Map对象
	 * @return 添加系列字段条件片段后的条件对象
	 */
	public Condition addField(Map<String, Object> keyValue) {
		this.addField(keyValue, this.conditionType, this.logicType, this.interrogation, this.prefix);
		return this;
	}

	/**
	 * 添加一个字段条件,可以指定条件选项(>,<等),其它选项全部使用默认设置
	 * 
	 * @param fieldName 字段名称
	 * @param fieldValue 字段的值
	 * @param cdtnType 条件选项的值
	 * @return 添加字段条件片段后的条件对象
	 */
	public Condition addField(String fieldName, Object fieldValue, String cdtnType) {// 此接口主要针对多变的条件类型而设置
		this.addField(fieldName, fieldValue, cdtnType, this.logicType, this.interrogation, this.prefix);
		return this;
	}

	/**
	 * 添加一个字段条件,并指定其中的每一个选项
	 * 
	 * @param fieldName 字段名
	 * @param fieldValue 字段值
	 * @param cdtnType 条件类型
	 * @param lgcType 逻辑类型
	 * @param itrGtn 是否使用占位符
	 * @param pfx 前缀
	 * @return 添加字段条件片段后的条件对象
	 */
	public Condition addField(String fieldName, Object fieldValue, String cdtnType, String lgcType, Boolean itrGtn, String pfx) {
		if (this.filter.isIgnore(fieldName, fieldValue)) {// 判定此字段是否应该被忽略掉
			return this;
		}
		cdtnType = cdtnType == null ? this.conditionType : cdtnType;
		lgcType = lgcType == null ? this.logicType : lgcType;
		itrGtn = itrGtn == null ? this.interrogation : itrGtn;
		pfx = pfx == null ? this.prefix : pfx;
		if (sqlBuffer.length() != 0) {
			sqlBuffer.append(" ").append(lgcType);
		}// " and name = "
		sqlBuffer.append(" ").append(pfx).append(fieldName).append(" ").append(cdtnType);
		if (itrGtn) {// 填充问号占位符型
			stuffInterrogation(fieldValue, cdtnType);
		} else {// 填充静态值类型
			stuffValue(fieldValue, cdtnType);
		}
		return this;
	}

	/**
	 * 添加一系列具有相同选项的字段条件,并且这些选项通过参数指定,这些条件用一个Map来进行包装
	 * 
	 * @param keyValue 一个包装字段条件的一个Map
	 * @param cdtnType 条件类型
	 * @param lgcType 逻辑类型
	 * @param itrGtn 是否使用占位符形式
	 * @param pfx 前缀
	 * @return 添加系列字段条件片段后的条件对象
	 */
	public Condition addField(Map<String, Object> keyValue, String cdtnType, String lgcType, Boolean itrGtn, String pfx) {
		for (Map.Entry<String, Object> entry : keyValue.entrySet()) {
			this.addField(entry.getKey(), entry.getValue(), cdtnType, lgcType, itrGtn, pfx);
		}
		return this;
	}

	/**
	 * 添加一个null字段条件
	 * 
	 * @param fieldName 字段名
	 * @param lgcType 逻辑类型
	 * @return 添加null条件片段后的条件对象
	 */
	public Condition addNull(String fieldName, String lgcType) {
		if (this.hasCondition()) {
			this.sqlBuffer.append(" ").append(lgcType);
		}
		this.sqlBuffer.append(" ").append(fieldName).append(" is null");
		return this;
	}

	/**
	 * 添加一个not null字段条件
	 * 
	 * @param fieldName 字段名
	 * @param lgcType 逻辑类型
	 * @return 添加not null条件片段后的条件对象
	 */
	public Condition addNotNull(String fieldName, String lgcType) {
		if (this.sqlBuffer.length() != 0) {
			this.sqlBuffer.append(" ").append(lgcType);
		}
		this.sqlBuffer.append(" ").append(fieldName).append(" is not null");
		return this;
	}

	/**
	 * 添加原始的sql语句
	 * 
	 * @param other 原始的sql语句,原始的sql语句必须空格开始
	 * @param os sql语句中占位符对应的值
	 * @return 添加原始条件语句后的条件对象
	 */
	public Condition addOther(String other, Object[] os) {
		this.sqlBuffer.append(other);
		if (os != null) {
			for (Object o : os) {
				this.valueList.add(o);
			}
		}
		return this;
	}
	
	public Condition addOther(String other, Object[] os, String lgcType){
		if (hasCondition()) {
			this.sqlBuffer.append(" ").append(lgcType);
		}
		this.sqlBuffer.append(other);
		if (os != null) {
			for (Object o : os) {
				this.valueList.add(o);
			}
		}
		return this;
	}

	/**
	 * 添加排序字段
	 * 
	 * @param orderByField 需要排序的字段
	 * @return 添加排序后的条件
	 */
	public Condition addOrderBy(String orderByField) {
		this.addOrderBy(orderByField, "desc", false);
		return this;
	}
	
	public Condition addOrderBy(String orderByField, String sc) {
		this.addOrderBy(orderByField, sc, false);
		return this;
	}

	/**
	 * 添加排序字段
	 * 
	 * @param orderByField 需要排序的字段
	 * @param sc 升降(asc或desc)
	 * @return 添加排序后的条件
	 */
	public Condition addOrderBy(String orderByField, String sc, boolean first) {
		if (orderByField == null || "".equals(orderByField.trim())) {
			return this;
		}
		if (sc==null) {
			sc = "";
		}
		if (this.orderByBuffer.length() == 0) {
			this.orderByBuffer.append(" order by ").append(orderByField).append(" ").append(sc);
			return this;
		}
		if (first) {
			this.orderByBuffer.insert(" order by ".length(), orderByField+" "+sc+",");
		} else {
			this.orderByBuffer.append(", ").append(orderByField).append(" ").append(sc);
		}
		return this;
	}
	
	/**
	 * 添加另一个条件对象,相当于逻辑运算
	 * 
	 * @param condition 要添加的逻辑对象
	 * @param lgcType 逻辑类型
	 * @return 返回当前的条件对象
	 */
	public Condition addCondition(Condition condition, String lgcType) {
		if (condition == null) {
			return this;
		}
		if (this.hasCondition() && condition.hasCondition()) {
			this.sqlBuffer.append(" ").append(lgcType);
		}
		this.sqlBuffer.append(condition.sqlBuffer);
		this.valueList.addAll(condition.valueList);
		if (condition.hasOrderBy() && this.hasOrderBy()) {
			this.orderByBuffer.append(", " + condition.orderByBuffer.substring(" order by".length()));
		} else {
			this.orderByBuffer.append(condition.orderByBuffer);
		}
		return this;
	}

	public Condition addCondition(Condition condition) {
		if (condition == null) {
			return this;
		}
		return this.addCondition(condition, condition.logicType);
	}

	/**
	 * 为此条件对应的SQL语句添加括号
	 * 
	 * @return
	 */
	public Condition addParentheses() {
		if (this.hasCondition()) {
			this.sqlBuffer.insert(0, " (").append(")");
		}// 这里有隐患
		return this;
	}

	private Boolean addDefaultOrderBy = true;
	
	public Boolean getAddDefaultOrderBy() {
		return addDefaultOrderBy;
	}

	public void setAddDefaultOrderBy(Boolean addDefaultOrderBy) {
		this.addDefaultOrderBy = addDefaultOrderBy;
	}

	/**
	 * 清除缓存,但是并不重置默认配置项
	 */
	public Condition reset() {
		this.sqlBuffer.setLength(0);
		this.orderByBuffer.setLength(0);
		this.valueList.clear();
		this.addDefaultOrderBy = true;
		return this;
	}

	/**
	 * 获取此条件的SQL语句,但是它并不在条件语句前加上某个逻辑关系符
	 * 
	 * @return
	 */
	public String getSql() {
		return this.sqlBuffer.toString() + this.orderByBuffer.toString();
	}

	/**
	 * 获取最终的SQL语句
	 * 
	 * @param firstLogicType 一般的取值为:and,or,not或为null
	 * @return 条件对应的SQL语句
	 */
	public String getSql(String firstLogicType) {
		firstLogicType = firstLogicType == null ? this.logicType : firstLogicType;
		if (this.hasCondition()) {
			return " " + firstLogicType + this.sqlBuffer.toString() + this.orderByBuffer.toString();
		} else {
			return this.orderByBuffer.toString();
		}
	}
   
	public boolean hasOrderBy() {
		return this.orderByBuffer.length() > 0;
	}

	public boolean hasCondition() {
		return this.sqlBuffer.length() > 0;
	}

	/**
	 * 获取条件语句所有占位对应的值列表
	 * 
	 * @return
	 */
	public List<Object> getValueList() {
		return this.valueList;
	}

	/**
	 * 设置默认的配置
	 * 
	 * @param conditionType 默认条件类型
	 * @param logicType 默认逻辑关系类型
	 * @param interrogation 默认是否使用占位符
	 * @param prefix 默认字段的前缀
	 * @return 返回当前条件对象
	 */
	public Condition setConfig(String conditionType, String logicType, Boolean interrogation, String prefix) {
		this.conditionType = conditionType == null ? this.conditionType : conditionType;
		this.logicType = logicType == null ? this.logicType : logicType;
		this.interrogation = interrogation == null ? this.interrogation : interrogation;
		this.prefix = prefix == null ? this.prefix : prefix;
		return this;
	}

	/**
	 * 设置默认的条件类型
	 * 
	 * @param conditionType 默认的条件类型
	 * @return 返回当前条件对象
	 */
	public Condition setConditionType(String conditionType) {
		this.conditionType = conditionType;
		return this;
	}

	@SuppressWarnings("unchecked")
	private void stuffInterrogation(Object fieldValue, String cdtnType) {
		if ("like".equalsIgnoreCase(cdtnType)) {// 如果是like条件,则fieldValue一定是一个字符串类型
			this.sqlBuffer.append(" ?");
			this.valueList.add("%" + fieldValue + "%");
		} else if ("in".equalsIgnoreCase(cdtnType) || "not in".equalsIgnoreCase(cdtnType)) {// in类型的条件fieldValue必须是一个列表
			this.sqlBuffer.append(" (");
			for (int i = 0, len = ((List) fieldValue).size(); i < len; i++) {
				this.sqlBuffer.append("?, ");
			}
			this.sqlBuffer.replace(this.sqlBuffer.length() - 2, this.sqlBuffer.length(), ")");
			this.valueList.addAll((List) fieldValue);
		} else if ("between".equalsIgnoreCase(cdtnType)) {// between类型的条件fieldValue必须是一个有两个元素的列表
			this.sqlBuffer.append(" ? and ?");
			this.valueList.addAll((List) fieldValue);
		} else {// 对于普通条件类型:=,>,<,>=,<=,<>
			this.sqlBuffer.append(" ?");
			this.valueList.add(fieldValue);
		}
	}

	@SuppressWarnings("unchecked")
	private void stuffValue(Object fieldValue, String cdtnType) {
		if (fieldValue instanceof String) {
			fieldValue = "like".equalsIgnoreCase(cdtnType) ? "'%" + fieldValue + "%'" : "'" + fieldValue + "'";
		} else if (Date.class.isAssignableFrom(fieldValue.getClass())) {// 注意时,分,秒的格式:HH24:mi:ss(oracle特有)
			// FIXME 这里只是针对oracle的一种处理方式
			fieldValue = "to_date('" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(fieldValue) + "', 'yyyy-MM-dd HH24:mi:ss')";
		}
		if ("like".equalsIgnoreCase(cdtnType)) {// 如果是like条件,则fieldValue一定是一个字符串类型
			this.sqlBuffer.append(" ").append(fieldValue);
		} else if ("in".equalsIgnoreCase(cdtnType) || "not in".equalsIgnoreCase(cdtnType)) {// in类型的条件fieldValue必须是一个列表
			List fv = (List) fieldValue;
			Object o = null;
			this.sqlBuffer.append(" (");
			for (Iterator iter = fv.iterator(); iter.hasNext();) {
				o = iter.next();
				this.sqlBuffer.append(o instanceof String ? "'" + o + "', " : o + ", ");
			}
			this.sqlBuffer.replace(this.sqlBuffer.length() - 2, this.sqlBuffer.length(), ")");
		} else if ("between".equalsIgnoreCase(cdtnType)) {// between类型的条件fieldValue必须是一个有两个元素的列表
			List fv = (List) fieldValue;
			Object o = fv.get(0);
			this.sqlBuffer.append(" ").append(o instanceof String ? "'" + o + "' " : o + " ").append("and");
			o = fv.get(1);
			this.sqlBuffer.append(" ").append(o instanceof String ? "'" + o + "' " : o + "");
		} else {// 对于普通条件类型:=,>,<,>=,<=,<>
			this.sqlBuffer.append(" ").append(fieldValue);
		}
	}

	/** 条件对应的可能为上面两种形式SQL语句的混合形式 */
	private StringBuffer	sqlBuffer		= new StringBuffer();

	private StringBuffer	orderByBuffer	= new StringBuffer();

	/** 用来存放第三种SQL语句中所有占位符对应变量值 */
	private List<Object>	valueList		= new ArrayList<Object>();

	/** 字段域的条件类型,可能的取值有:=,>,<,>=,<=,<>,like,in,not in,between */
	private String			conditionType	= "=";

	/** 多个字段域之间的逻辑关系可以是:and,or,not */
	private String			logicType		= "and";

	/** 是否使用?占位符 */
	private boolean			interrogation	= true;

	/** 字段的前缀,一般是根据需要设置的表的别名 */
	private String			prefix			= "";

	/** 判断给出的条件字段是否有效,主要通过字段的值判定 */
	private Filter			filter			= new EmptyFilter();

	public void setFilter(Filter filter) {
		this.filter = filter;
	}

	public Filter getFilter() {
		return this.filter;
	}

	public StringBuffer getOrderByBuffer() {
		return orderByBuffer;
	}

	public StringBuffer getSqlBuffer() {
		return sqlBuffer;
	}

	@Override
	public String toString() {
		return "\n条件的SQL部分:" + this.sqlBuffer + "\n条件的占位符值列表:" + this.valueList;
	}

	public Condition() {
	}

	public Condition(Filter filter) {
		this.filter = filter != null ? filter : new NoneFilter();
	}

	public interface Filter {
		public boolean isIgnore(String fieldName, Object fieldValue);
	}

	class EmptyFilter implements Filter {
		public boolean isIgnore(String fieldName, Object fieldValue) {
			if (fieldValue == null || fieldValue instanceof String && "".equals(fieldValue) || fieldValue instanceof Integer && new Integer(0).equals(fieldValue)) {
				return true;
			} else {
				return false;
			}
		}
	}

	class NoneFilter implements Filter {
		public boolean isIgnore(String fieldName, Object fieldValue) {
			return false;
		}
	}

}
 
分享到:
评论

相关推荐

    行业分类-设备装置-片体集中处理设备.zip

    这个压缩包文件“行业分类-设备装置-片体集中处理设备.zip”显然包含了与这类设备相关的详细资料,主要文档为“片体集中处理设备.pdf”,下面我们将深入探讨这一主题。 片体,通常指的是薄而平的物体,如半导体晶圆...

    模糊查询刷新时显示查询的条件

    这种方法简单直观,但不适合处理大量或复杂的查询条件。 3. **路由状态管理**:在使用前端路由(如React Router或Vue Router)的SPA(单页应用)中,可以将查询条件作为路由的一部分,刷新页面时路由信息依然保留。...

    mysql查询根据列按条件统计总数

    在统计分析中,子查询常用于先计算出中间结果,然后再基于这些结果进行进一步的处理。 ```sql SELECT * FROM ( SELECT 列1, COUNT(*) AS cnt FROM t1 GROUP BY 列1 ) AS sub UNION SELECT '总计', SUM(cnt) FROM ...

    处理百万级以上的数据提高查询速度的方法

    在处理百万级甚至更大规模的数据时,提高查询速度至关重要,因为大数据量的处理往往会导致查询效率低下,影响系统的整体性能。以下是一些针对大数据查询优化的关键策略和技巧: 1. **避免使用否定操作符**:在`...

    关联关系按条件查询细

    在软件开发中,尤其是在涉及到数据库操作的场景,关联关系按条件查询是一项基础且重要的技能。关联关系是指在数据库设计中,不同表之间的联系,如一对一、一对多、多对多等。本文主要讨论了如何在Java环境下,利用...

    SQL Server查询中的特殊字符处理

    总结起来,理解并正确处理SQL Server查询中的特殊字符是编写高效且无误的查询的关键。熟悉这些特殊字符的用法和转义规则,能够帮助开发者编写出更加精确和灵活的查询语句,提高数据检索的效率和准确性。

    数据库查询通用类

    4. **结果处理**:通用查询类可能包含将查询结果转化为对象(如JavaBean)的方法,便于进一步处理。这通常涉及到Java反射API。 5. **事务处理**:对于涉及多个数据库操作的情况,类应支持事务管理,确保数据的一致...

    污水集中式处理和分散式处理的比较.pdf

    2. 技术成熟:集中处理采用的技术通常较为成熟,如活性污泥法、A/O法、A2/O法等,处理效果稳定,污染物去除率高。 3. 统一管理:便于集中控制和管理,有利于环境保护政策的执行和监管。 然而,集中处理也存在以下...

    vue组合查询条件源码

    3. **计算属性与侦听器**:在Vue中,可以使用计算属性来处理查询条件的组合,例如根据多个输入字段动态生成查询参数。同时,使用侦听器(watcher)可以监听这些字段的变化,实时更新查询结果。 4. **Vuex**:对于...

    行业文档-设计装置-城市污水垃圾集中处理装置.zip

    城市污水和垃圾集中处理是现代城市管理中的重要环节,旨在保护环境、提高资源利用率。这份"行业文档-设计装置-城市污水垃圾集中处理装置.zip"压缩包包含了一份名为"城市污水垃圾集中处理装置.pdf"的详细文档,将为...

    行业分类-设备装置-一种便于集中处理的具有压缩功能的智能型垃圾桶.zip

    本文将深入探讨标题和描述中提及的“一种便于集中处理的具有压缩功能的智能型垃圾桶”的相关知识点。 首先,我们来理解这种智能型垃圾桶的核心特点——压缩功能。传统的垃圾桶往往因为容量有限,需要频繁清空,而...

    jsp+MYSQL编写的按条件查询代码

    根据提供的文件信息,我们可以分析出该段代码是用于实现基于 JSP 和 MySQL 的按条件查询功能。接下来将详细解析此代码的关键部分,并提取其中的重要知识点。 ### 一、JSP与MySQL连接 #### 1. **引入必要的包** 在...

    行业文档-设计装置-有机垃圾的集中处理系统.zip

    《有机垃圾的集中处理系统》 在环保与可持续发展的大背景下,有机垃圾的处理成为了一个重要的议题。有机垃圾,主要包括食物残渣、园林废弃物、农业剩余物等,如果不妥善处理,不仅会占用大量土地,还会产生恶臭,...

    DL/T 698-1999低压电力用户集中抄表系统技术条件

    ### DL/T 698-1999低压电力用户集中抄表系统技术条件 #### 1. 背景介绍 《DL/T 698-1999低压电力用户集中抄表系统技术条件》是中华人民共和国电力行业的一项重要标准。此标准于2000年2月24日由国家经济贸易委员会...

    垃圾分类处理与清运方案设计

    3. 有害垃圾运送到固废处理中心集中处理。 4. 其他不可回收垃圾将运送到填埋场或焚烧场处理。 所有垃圾将从小区运送到附近的转运站,再运送到少数几个垃圾处理中心。 本项研究课题旨在为深圳市的垃圾分类化进程...

    行业文档-设计装置-油烟净化集中处理系统.zip

    油烟净化集中处理系统是餐饮业和食品加工行业中重要的环保设施,其主要目的是通过高效过滤和吸附技术,将厨房产生的油烟进行净化,降低对环境的污染。这个压缩包文件"行业文档-设计装置-油烟净化集中处理系统.zip...

    自定义查询对象组件封装例子

    解析过程应考虑所有可能的查询条件,确保处理各种复杂的查询需求。 5. **最佳实践**: - **分离关注点**:确保查询逻辑集中在服务层,表示层只负责接收和转发请求。 - **错误处理**:在解析查询对象时,对可能...

    危险废物集中处理处置关键技术研究与示范.doc

    【危险废物集中处理处置关键技术研究与示范】 危险废物是指具有毒性、腐蚀性、传染性、化学反应性或易燃易爆性的废弃物,它们对人类健康和环境构成巨大威胁。在中国,由于工业发展和日常生活,这类废物的产量大、...

    行业资料-建筑装置-带式输送机粉尘集中处理装置.zip

    《带式输送机粉尘集中处理装置》 在建筑行业中,带式输送机是常见的物料运输设备,广泛应用于矿山开采、建材、电力等多个领域。然而,带式输送机在运行过程中会产生大量的粉尘,不仅影响工作环境,还可能对工人的...

Global site tag (gtag.js) - Google Analytics