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;
}
}
}