关于mybatis-plus在多条件搜索情况下的代码优化.

963 阅读2分钟

最近时间多,于是开始学习java. 目前就关于mbp在多条件搜索的情况下的一些优化思路做一个分享,

先说明需求: image.png

如上图的表格中所示该table有多个列,假设每个列都支持搜索,在springboot中用到实体类Employee接收,在一般情况下

代码就会这样:

image.png

目前只是伪代码还没加入非空判断,假设搜索项有十几二十个就要手写十几个"eq","like","in"并且还要做非空判断这样的代码十分不优雅,所以mbp提供了一套比较简洁的查询方式. 如图所示:

image.png

在加入这个注解之后name字段的搜索sql就会以like的条件进行搜索, 然后再service层直接在queryWrapper中传入对应的实体类:

image.png

这样就可以实现非常简洁的多条件搜索 但是问题来了,目前的SQLCondition中官方给的常量只有以下六个:

image.png

官方说是可以自定义,然后我就自定义了in查询 字符串应该是 "%s in (#{%s})",但是搜索出来的条件并不正确,我在想应该是sql直接把括号中的内容当成字符串了无法解析,所以如果无法用注解实现in查询(这个待大佬解答,我也不清楚为啥),这个关于queryWrapper传参的用法就很鸡肋,所以打算自己实现一套比较简洁的查询方式,顺便也了解一下java注解的原理. 首先创建一个自定义注解:

image.png

默认值为eq 可以传入 like 或 in 使用方式:

image.png

然后创建一个SeachConditionUtils

public class SearchConditionUtils<T> {
    private T entity;
    private QueryWrapper queryWrapper;
    private Class c;
    public SearchConditionUtils(T entity, QueryWrapper queryWrapper){
        this.entity = entity;
        this.queryWrapper = queryWrapper;
        this.c = entity.getClass();
        Field[] fields = this.c.getDeclaredFields();
        for(Field field : fields){
            String fieldName = field.getName();
            String fieldValue = getFieldValue(fieldName);
            String conditionType = getAnnotation(field);
            linkCondition(fieldName,fieldValue,conditionType);
        }

    }
    public void linkCondition(String fieldName,String fieldValue,String conditionType){
        if(conditionType.equals("eq")){
            if(hasFieldValue(fieldValue)){
                queryWrapper.eq(fieldName,fieldValue);
            }
        }
        if(conditionType.equals("like")){
            if(hasFieldValue(fieldValue)){
                queryWrapper.like(fieldName,fieldValue);
            }
        }
        if(conditionType.equals("in")){
            if(hasFieldValue(fieldValue)){
                queryWrapper.in(fieldName,fieldValue.split(","));
            }
        }
    }
//    public void linkEqCondition(String fieldName,String fieldValue){
//
//    }
//    public void linkLikeCondition(String fieldName,String fieldValue){
//
//    }
//    public void linkInCondition(String fieldName,String fieldValue){
//
//    }
    public Boolean hasFieldValue(String fieldValue){
        return fieldValue != null && !fieldValue.equals("");
    }
    public String getFieldValue(String fieldName){
        String methodName = getMethodName(fieldName);
        String value = "";
        try {
          Method method = c.getDeclaredMethod(methodName,null);
          value =(String) method.invoke(entity,null);
        }catch (Exception e){
    System.out.println(e);
        }
        return value;

    }
    public String getAnnotation(Field field){
        String value = "eq";
        CustomAnnotation customAnnotation =  field.getAnnotation(CustomAnnotation.class);
        if(customAnnotation !=null){
            value = customAnnotation.value();
        }
        return value;
    }
    public String getMethodName(String fieldName){
        return "get" + fieldName.substring(0,1).toUpperCase()+ fieldName.substring(1);
    }
}

在service中直接创建searchCondtionUtils实例传入employee 和 queryWrapper 就可以实现对queryWrapper的优雅查询,不需要写大量的if不需要写大量的条件判断。 刚学java不懂以上的解决方式是否最优,待大佬点评。