`
qq1988627
  • 浏览: 103283 次
  • 性别: 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;
		}
	}

}
 
分享到:
评论

相关推荐

    基于R树的方向关系查询处理

    方向关系查询处理需要执行方向连接操作,目前有关空间连接的研究主要集中在拓扑关系和距离关系方面,而较少考虑方向关系.研究了基于R树的方向关系查询处理方法,定义了四元组模型表示对象MBR间的方向关系,提出了基于R树...

    MySQL查询条件常见用法详解

    where后面支持多种运算符,进行条件的处理 比较运算符 逻辑运算符 模糊查询 范围查询 空判断 比较运算符 等于: = 大于: &gt; 大于等于: &gt;= 小于: &lt; 小于等于: &lt;= 不等于: != 或 &lt;&gt; 例1:查询编号大于3的学生 ...

    铁路6502电气集中故障处理模拟软件

    Twx-6502电气集中模拟教学台,是以std工业控制机,全部联锁表示条件由计算机格局操作自动生产,将操作人员办理结果显示在控制台上,具有操作及标识信息与现场操纵台一致的功能,模拟行车运营和各种信号故障状态的...

    6502电气集中及计算机联锁系统操作使用问答

    的操作使用、异常现象的处理,并对半自动闭塞条件下 的应用等作了适当介绍;第三部分为计算机联锁的操 作使用知识。条理清晰,浅显易懂,针对性强。 适合配置6502继电集中及计算机联锁车站的车站值班员和信号员...

    论文研究-基于集中式存储的全局约束并行相容模型.pdf

    为了利用多处理平台的并行处理能力, 提高约束求解中相容检查的效率, 提出了一种新的基于集中式存储的全局约束并行相容模型。利用动态分配约束条件的方法解决负载均衡问题; 通过对变量域的集中式管理, 保证了冲突检测...

    油气集中处理站节能降耗与优化技术研究 (2015年)

    以油气集中处理站―高青联合站为例,确定年运行费用为目标函数,以外输油含水率为约束条件,以加药量和加热炉出口温度等为优化变量的优化数学模型。以实验研究为基础,用能量平衡理论对集输系统的用能情况进行全面...

    松软破碎带盘区集中巷耦合支护技术研究

    经过工程实践证实,采取锚索补强与注浆加固耦合支护手段后,该支护体系有效控制了围岩的变形和破坏,注浆加固处理约90 d天后,变形速度基本为零,满足了盘区巷道长期使用的需求,为此类地质条件下盘区巷道的加固提供了参考...

    集中式数据库系统中查询优化的概述-研究论文

    处理意外查询的有效方法是通用数据库管理系统成功的关键先决条件。 提出了多种提高查询评估算法性能的方法:基于逻辑的语义转换,基本操作的快速实现以及用于在替代访问计划之间生成和选择的组合或启发式算法。 本文...

    论文研究 - 越南顺化日河流域传统农业食品加工业村家庭的污水处理支付意愿:以河内市为例

    尽管有许多研究集中在生产活动的财务分析,技术解决方案和改善水质的研究上,但尚未进行关于适用于工艺村水质管理的经济手段的应用研究,以及WTP的一些研究。也。 这项研究旨在估算越南Nhue-Day流域某些传统农业食品...

    分布式数据库试题及答案.doc

    5.4. 按如下给出的条件,求出半连接优化计划和执行场地,并作后优化处理 32 5.5. 下面是当一个数据库系统出现故障时,日志文件中的信息 36 5.5.1. 画出对应的事务并发执行图。 37 5.5.2. 找出发生故障时系统中的活动...

    乳化液集中配比供液站的研究与应用

    因井下水质差,人工配比出来的乳化液精度低,影响液压设备性能,通过在井下安装水处理与变频条件下乳化液自动配比一体化装置,建设乳化液集中供液站,将配比好的乳化液输送到各个工作面,有效地保护了综采支架各元件,提高...

    计算机联锁控制系统中对特殊联锁条件的处理 (1998年)

    针对计算机联锁控制系统中对特殊联锁条件的处理,尤其是对到发线出岔的处理,在比较继电集中与计算机控制两种方法的基础上,阐明了计算机联锁控制系统对于像到发线出岔等的特殊联锁条件的处理。无论在功能上,还是在方法...

    分布式数据库系统-复习.doc

    局部查询 远程查询 全局查询 分布式查询处理可以分为 、 、 和 四层。 查询分解 数据本地化 全局优化 局部优化一个分布式事务通常是由 和 组成。 主事务 子事务 事务的四个特性是: 、 、 和 。 原子性 一致性 隔离...

    多级带式输送机远程集中控制系统设计

    为进一步提高多级带式输送机运行的可靠性,及时处理带式输送机的各类事故,并减少维修人员和巡检人员,设计了多级带式输送机远程集中控制系统。阐述了集控系统的组成、工作原理、控制功能、使用效果,详细介绍了集控系统...

    ORACLE数据库智能化管理系统2012

    批量处理查询结果集中数据去除多余前后空格,增加对多字段字符串数据标准化,替换或去除数据中任意数据位数据,使其达到你想要的数据。 自动创建并可导出全数据库同义词创建语句,省去了你书写的麻烦。 您可以自由...

    SQL语言艺术

    看似高效的查询条件 抽象层 分布式系统 动态定义的搜索条件 9 多条战线:处理并发 数据库引擎作为服务提供者 并发修改数据 10 集中兵力:应付大数据量 增长的数据量 数据仓库 11 精于计谋:挽救响应时间 数据的行列...

    数据挖掘weka数据分类实验报告.doc

    该数据集中的全部实例共可分为三类:Iris Setosa、Iris Versicolour和Iris Virginica。 实验数据集中所有的数据都是实验所需的,因此不存在属性筛选的问题。若所采用的 数据集中存在大量的与实验无关的属性,则需要...

    考虑集中质量的旋转悬臂梁的动力学建模与频率分析 (2011年)

    引入无量纲变量,对横向振动动力学方程做无量纲化处理,通过数值计算分析集中质量对柔性梁横向弯曲振动固有频率的影响。研究发现,随着集中质量比率的增大,第1阶固有频率轨迹线在下降;悬臂梁横向

    Hibernate框架参考文档

    15. 条件查询(Criteria Queries); 16. Native SQL查询; 17. 过滤数据; 18. XML映射; 19. 提升性能; 20. 工具箱指南; 21. 示例:父子关系(Parent Child Relationships); 22. 示例:Weblog 应用程序; 23. 示例:复杂...

    每小时5吨实验室污水处理设备流程说明.docx

    1.实验室废水经现场污水管道收集后集中至污水主管道(规格:φ50,材质:UPVC)后自流进入废水收集箱内,废水收集箱为PE材质,收集箱主要作用为调节水量、均化水质。废水收集箱内液位到达高液位,污水提升泵自动启动...

Global site tag (gtag.js) - Google Analytics