码迷,mamicode.com
首页 > 数据库 > 详细

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

时间:2015-08-12 15:04:29      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:hibernate   sql   查询语句   


最近比较懒,所以进度很慢很慢。技术分享


在此之前我已经有对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

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

标签:hibernate   sql   查询语句   

原文地址:http://7041393.blog.51cto.com/7031393/1683844

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!