在此之前我已经有对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没办法用,只需就这个对象简单的更改就可以使用。懒点下次更改吧。
差不多就是这样子吧,本人小菜一枚,表达能力也不是很好。请大神们见谅。初学者还有很多要学的,请大神多指教。
继续对JFinal的Model部分包装一下,github地址:
https:
//github.com/cnzzs/zjf
本文出自 “7031393” 博客,请务必保留此出处http://7041393.blog.51cto.com/7031393/1683844
原文地址:http://7041393.blog.51cto.com/7031393/1683844