您的位置:首页 > 数据库

对sql的查询语句做成对象式,简单实现。Where部分

2015-08-12 00:44 1051 查看
最近比较懒,所以进度很慢很慢。



在此之前我已经有对sql查询语句的包装,连接地址:http://7041393.blog.51cto.com/7031393/1680736

sql的包装先定义了一个简单的接口
package net.zz.zjf.plugin;
/**
* Created by ZaoSheng on 2015/7/15.
*/
public interface SQLParams {
String toFormatSQL();
String toSQL();
}


这个接口暂时就两个方法。toSQL()这个方法用来生成条件参数为":property"的sql,而toFormatSQL()是用来生成条件参数为"?"的sql,这里如果是hibernate的话建议试用toSQL()。

对此我对之前的QueryParams进行了一个扩展,对具体sql进行拆分成具体对象。这里我就先讲讲我where的实现。
在使用where 需要用到两个枚举

第一个AndOr,这个枚举类很简单吧,不想在对此解释了。

package net.zz.zjf.plugin;

/**
* Created by ZaoSheng on 2015/8/5.
*/
public enum AndOr {
AND{
@Override
public String toMatchString(String propertyName, String pattern) {
return String.format(" and %s %s ", propertyName, pattern);
}
}, OR{
@Override
public String toMatchString(String propertyName, String pattern) {
return String.format(" or %s %s ", propertyName, pattern);
}
}, NUL{
@Override
public String toMatchString(String propertyName, String pattern) {
return String.format(" %s %s ", propertyName, pattern);
}
};
public abstract String toMatchString(String propertyName, String pattern);
}
接下来Restriction这个类在之前那篇文章里面提到过的枚举类,只是对现需求进行一个扩展。一样不进行解释。
package net.zz.zjf.plugin;

/**
* Created by ZaoSheng on 2015/7/30.
*/
public enum Restriction {

/**
* 等于查询(from Object o where o.property = ?)
*/
EQ {
public String toMatchString(String pattern) {
return "= :" + pattern;
}
},

/**
* 非等于查询(from Object o where o.property <> ?)
*/
NE {
public String toMatchString(String pattern) {
return "<> :" + pattern;
}
},

/**
* 大于等于查询(from Object o where o.property >= ?)
*/
GE {
public String toMatchString(String pattern) {
return ">= :" + pattern;
}

},

/**
* 大于查询(from Object o where o.property > ?)
*/
GT {
@Override
public String toMatchString(String pattern) {
return "> :" + pattern;
}
},

/**
* 小于等于查询(from Object o where o.property <= ?)
*/
LE {
@Override
public String toMatchString(String pattern) {
return "<= :" + pattern;
}
},

/**
* 小于查询(from Object o where o.property < ?)
*/
LT {
@Override
public String toMatchString(String pattern) {
return "< :" + pattern;
}
},
/**
* 两个值之间查询(from Object o where o.property between ? and ?)
*/
BETWEEN {
@Override
public String toMatchString(String pattern) {
return String.format("%s between :%s1 and :%s2", pattern, pattern, pattern);
}
},

/**
* 包含查询(from Object o where o.property in(?,?,?))
*/
IN {
@Override
public String toMatchString(String pattern) {
return String.format("in (:%s)" , pattern);
}
},

/**
* 非包含查询(from Object o where o.property not in(?,?,?))
*/
NIN {
@Override
public String toMatchString(String pattern) {
return String.format("not in ( :%s )" , pattern);
}
},

/* *
* 左模糊查询(from Object o where o.property like %?)
*/
LLIKE {
@Override
public String toMatchString(String pattern) {
return "%" + pattern;
}
},

/* *
* 右模糊查询(from Object o where o.property like ?%)
*/
RLIKE {
@Override
public String toMatchString(String pattern) {
return pattern + '%';
}
},

/* *
* 模糊查询(from Object o where o.property like %?%)
*/
LIKE {
@Override
public String toMatchString(String pattern) {
return '%' + pattern + '%';
}
},
/* *
* 模糊查询(from Object o where o.property  is null)
*/
NULL {
@Override
public String toMatchString(String pattern) {
return  pattern + " is null";
}
},
/* *
* 模糊查询(from Object o where o.property is not null)
*/
NOTNULL  {
@Override
public String toMatchString(String pattern) {
return  pattern + " is not null";
}
};

public abstract String toMatchString(String pattern);
}
这里对where的解释,我就直接把代码贴出来,讲一些解释在代码里面写注释吧(因为本人表达能力不是很好)!

package net.zz.zjf.plugin;

import java.lang.reflect.Array;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Created by ZaoSheng on 2015/8/5.
*/
public class Where implements SQLParams{
//用于存放第一个条件的名
private String first = null;
/*这里存放所有的where需要用到的东西。wheres的key是property名,value主要分为三部分
*value主要分为三部分,value[0]用来存放property的值,在BETWEEN的情况下value[0]是数组
*数组长度为2。value[1]存放AndOr,value[2]存放具体的where操作,比如 ">",">=","like","in"
*等操作。
*/
private Map<String, Object[]> wheres = new HashMap<String, Object[]>();
//这个对象用来存放具体的属性值attrs的key是sql中":property"中的"property",value是对应的值
private Map<String, Object> attrs = new HashMap<String, Object>();
//这个集合不一定有值,在执行toFormatSQL方法后才会有值。存放的值依次对应sql中的第几个"?"
private List<Object> paras = new ArrayList<Object>();

public Where() {

}

public Where(String propertyName, Object value, AndOr andor, Restriction restriction) {
first = propertyName;
add(propertyName, value, andor, restriction);
}

public Where(String propertyName, Object value, AndOr andor) {
this(propertyName, value, andor, Restriction.EQ);
}

public Where(String propertyName, Object value, Restriction restriction) {
this(propertyName, value, AndOr.NUL, restriction);
}

public Where(String propertyName, Object value) {
this(propertyName, value, Restriction.EQ);
}

public Map<String, Object[]> getWheres() {
return wheres;
}

public Map<String, Object> getAttrs() {
return attrs;
}

public List<Object> getParas() {
return paras;
}

public Where and(String propertyName, Object value, Restriction restriction) {
add(propertyName, value, AndOr.AND, restriction);
return this;
}

public Where and(String propertyName, Object value) {
return and(propertyName, value, Restriction.EQ);
}

public Where or(String propertyName, Object value, Restriction restriction) {
add(propertyName, value, AndOr.OR, restriction);
return this;
}

public Where or(String propertyName, Object value) {
return or(propertyName, value, Restriction.EQ);
}

protected void add(String key, Object value, AndOr andor, Restriction restriction) {
if (null == value || "".equals(value)) {
if (key.equals(first))
{
first = null;
}
wheres.remove(key);
} else {
wheres.put(key, new Object[]{value, andor, restriction});
}

}

public String toSQL() {
if (wheres.isEmpty()) return "";
StringBuilder sb = new StringBuilder();
if (null != first)  setSql(first, wheres.get(first), sb );

for (String key : wheres.keySet()) {
if (key.equals(first))  continue;

Object[] objects = wheres.get(key);
setSql(key, objects, sb);

}
return sb.toString();
}

/**
*这个方法之所以提取出来是因为能更好的在多个地方引用(应该用代码重构的方式来讲的,可惜我不会讲).
*/
private void setSql(String key, Object[] objects, StringBuilder sb)
{
AndOr andOr = (AndOr) objects[1];
Restriction restriction = (Restriction)objects[2];
switch (restriction) {
case LIKE:
case LLIKE:
case RLIKE:
sb.append(andOr.toMatchString(key, "like :" + key));
attrs.put(key, restriction.toMatchString(objects[0].toString()));
break;
case NULL:
case NOTNULL:
sb.append(andOr.toMatchString("", restriction.toMatchString(key)));
break;
case BETWEEN:
sb.append(andOr.toMatchString(key, restriction.toMatchString(key)));
Object[] value = (Object[]) objects[0];
attrs.put(String.format("%s1", key),  value[0]);
attrs.put(String.format("%s2", key),  value[1]);
break;
default:
sb.append(andOr.toMatchString(key, restriction.toMatchString(key)));
attrs.put(key, objects[0]);
}
}

@Override
public String toFormatSQL() {
return  toFormatSQL(toSQL(), attrs, paras);
}

/**
* @param whereSQL
* @param attrs
* @param values
* @return
*/
public static String toFormatSQL(String whereSQL, Map<String, Object> attrs, List<Object> values) {
Matcher matcher = Pattern.compile(":(\\w+)").matcher(whereSQL);
String rexp = null;
while (matcher.find()) {
String group = matcher.group(1);
Object ov = attrs.get(group);
if (ov instanceof List) {
StringBuilder sb = new StringBuilder();
List vs = (List) ov;
for (Object v : vs) {
sb.append("?,");
values.add(v);
}
sb.deleteCharAt(sb.length() - 1);
rexp = sb.toString();

} else {
values.add(ov);
rexp = "?";
}
whereSQL = whereSQL.replace(String.format(":%s", group), rexp);
}
return whereSQL;
}

@Override
public String toString() {
return toFormatSQL();
}

public static void main(String[] args) {
Calendar c = new GregorianCalendar();

Where where = new Where("name", "张三");
where.or("class", 2);
where.and("sex", true);
where.and("age", new Integer[]{1,10}, Restriction.BETWEEN);
List<Object> ids = new ArrayList<Object>();
ids.add(4);
ids.add(3);
where.and("id", ids, Restriction.IN);
System.out.println(where.toString());

for (Object value :where.getParas())
{
System.out.print(String.format("%s ", value));
}

}
}


写完发现NULL与NOTNULL没办法用,只需就这个对象简单的更改就可以使用。懒点下次更改吧。

差不多就是这样子吧,本人小菜一枚,表达能力也不是很好。请大神们见谅。初学者还有很多要学的,请大神多指教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  sql hibernate 查询语句