特殊QueryWrapper查询解决所有问题

可以先看以前的自定义查询
自定义的QueryMapper查询

现在我添加了注解查询,通过使用

    /** 用户账号 */
    @TableField(value = "user_name")
    @MapperQuery(queryType = QueryType.EQ)
    private String userName;

    /** 用户昵称 */
    @TableField(value = "nick_name")
    @MapperQuery(queryType = QueryType.NE)
    private String nickName;

通过使用@MapperQuery(queryType = QueryType.EQ)注解来统一的实现查询,但是这个是全局的,就是好比,这里希望使用eq(相等),然后那里希望使用ne(不相等)来查,注解到实体类上这个就不行了,这个只能满足全部都使用统一的,并且都是and连接的
方法代码如下


    /**
     * TODO 自定义遍历查询方法(通过注解)
     *
     * @param object
     * @return com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<T>
     * @author 猫颜
     * @date 下午9:20
     */
    public QueryWrapper<T> queryAllByAnnotation(T object) throws IllegalAccessException,
            NoSuchMethodException,
            InvocationTargetException {

        Class<?> aClass = object.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
//        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        //第一个为serialVersionUID(舍去) i为1 绕过
        //获取object的所有字段
        for (int i = 1; i < declaredFields.length; i++) {
            field = declaredFields[i];
            //类中的成员变量为private,故必须进行此操
            field.setAccessible(true);
//            不能直接获取到值,可以通过构造get方法,或者调用类的get方法来获取值
//            通过StringUtils的containsIgnoreCase方法来获取方法名称
//            通过上面那种方法,有循环嵌套,性能需要优化
//            所以采取拼接get方法名
/**
 *
 * @author 猫颜
 * @date         //获取属性名称
 *         for (Field field:
 *              declaredFields) {
 *             System.out.println(field.getName());
 *             methodNameFirst = field.getName().substring(0,1).toUpperCase();
 *             methodName = field.getName();
 *             methodName = "get"+methodNameFirst+methodName.substring(1);
 *             System.out.println("方法名称为:"+methodName);
 *
 * //            优化
 *             System.out.println("优化:"+"get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1));
 *         } 下午5:18
 * @param object
 * @return com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<T>
 */
//获取get方法名称
            getMethodName = "get" + declaredFields[i].getName().substring(0, 1).toUpperCase() + declaredFields[i].getName().substring(1);
            System.out.println(getMethodName);
//            执行get方法获取属性值
            //执行方法
            Method method = aClass.getMethod(getMethodName, null);
            Object getValue = method.invoke(object, null);
            //System.out.println("输出为:"+invoke);
//            System.out.println("优化:"+"get"+declaredFields[i].getName().substring(0,1).toUpperCase()+declaredFields[i].getName().substring(1));
//            如果值不为空,则添加到eq中
            if (getValue != null) {
                //映射关系
//                return super.eq(,field.get(object));
                //获取其注解的值
//                后面可以采用查询方法注释来解决,不同的查询所需的问题
                System.out.println("实体类的字段名: "+field.getName());
                System.out.println("表的列名值:" + field.getAnnotation(TableField.class).value());
                System.out.println("get获取值:" + getValue.toString());

//                获取MapperQuery注解的类型
                String mapperTypeName = field.getAnnotation(MapperQuery.class).queryType().name();

                switch(mapperTypeName){
                    case "EQ":
                        //等于
                        MyQueryWrapper.this.eq(field.getAnnotation(TableField.class).value(), getValue.toString());
                        break;
                    case "NE":
                        //不等于
                        MyQueryWrapper.this.ne(field.getAnnotation(TableField.class).value(), getValue.toString());
                        break;
                    case "GT":
                        //大于
                        MyQueryWrapper.this.gt(field.getAnnotation(TableField.class).value(), getValue.toString());
                        break;
                    case "GE":
                        //大于等于
                        MyQueryWrapper.this.ge(field.getAnnotation(TableField.class).value(), getValue.toString());
                        break;
                    case "LT":
                        MyQueryWrapper.this.lt(field.getAnnotation(TableField.class).value(), getValue.toString());
                        //小于
                        break;
                    case "LE":
                        MyQueryWrapper.this.le(field.getAnnotation(TableField.class).value(), getValue.toString());
                        //小于等于
                        break;
                    case "LIKE":
                        MyQueryWrapper.this.like(field.getAnnotation(TableField.class).value(), getValue.toString());
                        //存在
                        break;
                    case "NOTLIKE":
                        MyQueryWrapper.this.notLike(field.getAnnotation(TableField.class).value(), getValue.toString());
                        //不存在
                        break;
                    default:
                        //默认是eq
                        MyQueryWrapper.this.eq(field.getAnnotation(TableField.class).value(), getValue.toString());
                }
            }
                //MyQueryWrapper.this.eq(field.getAnnotation(TableField.class).value(), getValue.toString());
            }

        return MyQueryWrapper.this;
    }

所以我又新写了一个,可以自定义的查询,一个更好的查询,但是目前只支持单数值查询,就是说between这样的查不了,因为实体类的值就一个嘛。
方法代码如下


    /**
     * TODO 自定义查询方法
     *
     * @param object
     * @return com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<T>
     * @author 猫颜
     * @date 上午11:33
     */
    public QueryWrapper<T> queryAll(T object, HashMap<String, Object> queryRules) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
        Class<?> aClass = object.getClass();

//        for (Map.Entry<String,Object> entry:
//             queryRules.entrySet()) {
//            System.out.println("所有值"+entry.getKey());
//        }

        for (String declaredField :
                queryRules.keySet()) {

            if (StringUtils.equals(declaredField,"connect")){
                switch (String.valueOf(queryRules.get(declaredField))) {
                    case "AND":
                        //并且
                        break;
                    case "OR":
                        //或
                        MyQueryWrapper.this.or();
                        break;
                }

                continue;
            }


            field = aClass.getDeclaredField(declaredField);
            getMethodName = "get" + declaredField.substring(0, 1).toUpperCase() + declaredField.substring(1);
            method = aClass.getMethod(getMethodName, null);
            getValue = method.invoke(object, null);
            if (getValue != null&&field!=null) {

                System.out.println("实体类的字段名: " + declaredField);
                System.out.println("表的列名值:" + field.getAnnotation(TableField.class).value());
                System.out.println("get获取值:" + getValue.toString());
                switch (String.valueOf(queryRules.get(field.getName()))) {
                    case "EQ":
                        //等于
                        MyQueryWrapper.this.eq(field.getAnnotation(TableField.class).value(), getValue.toString());
                        break;
                    case "NE":
                        //不等于
                        MyQueryWrapper.this.ne(field.getAnnotation(TableField.class).value(), getValue.toString());
                        break;
                    case "GT":
                        //大于
                        MyQueryWrapper.this.gt(field.getAnnotation(TableField.class).value(), getValue.toString());
                        break;
                    case "GE":
                        //大于等于
                        MyQueryWrapper.this.ge(field.getAnnotation(TableField.class).value(), getValue.toString());
                        break;
                    case "LT":
                        MyQueryWrapper.this.lt(field.getAnnotation(TableField.class).value(), getValue.toString());
                        //小于
                        break;
                    case "LE":
                        MyQueryWrapper.this.le(field.getAnnotation(TableField.class).value(), getValue.toString());
                        //小于等于
                        break;
                    case "LIKE":
                        MyQueryWrapper.this.like(field.getAnnotation(TableField.class).value(), getValue.toString());
                        //存在
                        break;
                    case "NOTLIKE":
                        MyQueryWrapper.this.notLike(field.getAnnotation(TableField.class).value(), getValue.toString());
                        //不存在
                        break;
                }
            }
        }
        return MyQueryWrapper.this;
    }

这里不仅仅要把实体类传入,还需要传入一个规则,采用HashMap来保存规则
这里的QueryType是枚举类
代码如下

public enum QueryType {
    //并且(默认为and连接)
    AND,

    //或
    OR,

    //等于
    EQ,

    //不等于
    NE,

    //大于
    GT,

    //大于等于
    GE,

    //小于
    LT,

    //小于等于
    LE,

    //存在
    LIKE,

    //不存在
    NOTLIKE
}

暂时只写了这几个

然后就是调用方法

    @Test
    void test() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, NoSuchFieldException {
        DqUser dqUser = new DqUser();
        dqUser.setUserName("maoyan");
        dqUser.setNickName("猫颜");

        //Hashmap是无序的,所以要使用LinkedHashMap
        HashMap<String, Object> queryRules = new LinkedHashMap<>();
//        HashMap<String, Object> queryRules = new HashMap<>();
        queryRules.put("userName", QueryType.EQ);
        queryRules.put("connect",QueryType.OR);
        queryRules.put("nickName",QueryType.EQ);

        MyQueryWrapper<DqUser> myQueryWrapper = new MyQueryWrapper<>();
//        myQueryWrapper.queryAllByAnnotation(dqUser);
        myQueryWrapper.queryAll(dqUser,queryRules);
        //System.out.println(myQueryWrapper.allEq(dqUser));
//        QueryWrapper queryWrapper = new QueryWrapper<DqUser>();
//        queryWrapper.eq("nick_name","maoyan");
        DqUser dqUser1 = dqUserMapper.selectOne(myQueryWrapper);
        System.out.println(dqUser1);

        myQueryWrapper.clear();

    }

这里规则hashmap使用的是LinkedHashMap,因为hashmap传入没有规则,所以会乱,而LinkedHashMap是有规则的,当然你也可以更改代码为list,但是方法中也要相应的更改就可以了。
然后就是基本编写完成的论坛后端框架,功能都有,后续会慢慢让它变得更好
QucikDevelop论坛框架

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值