模仿mybatisPlus的条件构造器编写mongoDB的条件构造器

一. mybatisPlus与mongoDB条件构造器差异

  1. 先看示例
  • mybatisplus条件构造器
    list(Wrappers.lambdaQuery(OrderClass.class).select(OrderClass::getClassName).eq(!ObjectUtils.isEmpty(name),OrderClass::getClassName,name))
  • mongoDb条件构造器
    mongoTemplate.findOne(Query.query(Criteria.where("tacticsShopList").is(shopCode)), Map.class, "collectionName")
  1. 痛点
  • mondoDb的条件构造器没有非空判断条件参数,如果需要判断非空只能写另写判断
  • mondoDb的条件构造器的字段只能写字符串, 不能用Lambda表达式写

二. 自定义mongoDB条件构造器

针对上述痛点自定义mongoDB条件构造器

2.1 自定义函数接口

@FunctionalInterface
public interface SFunction extends Function, Serializable {
}

2.2 条件构造器

只写了部分条件,更多条件方法自己实现

public class CriteriaVo extends Criteria{

    public static CriteriaVo create(){
        return new CriteriaVo();
    }

    /**
     * 模糊匹配
     * @param fun
     * @param value
     * @return
     */
    public  CriteriaVo regexN (SFunction fun, String value){
        if(!ObjectUtils.isEmpty(value)){
            this.and(columnToString(fun)).regex(".*"+value)+".*");
        }
        return this;
    }

    /**
     * 精确匹配
     * @param fun
     * @param value
     * @return
     */
    public  CriteriaVo isN (SFunction fun,Object value){
        if(!ObjectUtils.isEmpty(value)){
            this.and(columnToString(fun)).is(value);
        }
        return this;
    }

    /**
     * 大于
     * @param fun
     * @param value
     * @param 
     * @return
     */
    public  CriteriaVo gteN (SFunction fun,Object value){
        if(!ObjectUtils.isEmpty(value)){
            this.and(columnToString(fun)).gte(value);
        }
        return this;
    }

    /**
     * 小于
     * @param fun
     * @param value
     * @param 
     * @return
     */
    public  CriteriaVo lteN (SFunction fun,Object value){
        if(!ObjectUtils.isEmpty(value)){
            this.and(columnToString(fun)).lte(value);
        }
        return this;
    }

    public  CriteriaVo elemMatchN (SFunction fun1, SFunction fun2, Object value){
        if(!ObjectUtils.isEmpty(value)){
            this.and(columnToString(fun1)).elemMatch(Criteria.where(columnToString(fun2)).is(value));
        }
        return this;
    }


    public static  String columnToString(SFunction func) {
        String fieldName = "";
        try {
            Method writeReplace = func.getClass().getDeclaredMethod("writeReplace");
            writeReplace.setAccessible(Boolean.TRUE);
            SerializedLambda serializedLambda = (SerializedLambda) writeReplace.invoke(func);
            String methodName = serializedLambda.getImplMethodName();
            if(methodName.startsWith("get") || methodName.startsWith("set")){
                fieldName =  methodName.substring(3);
            }else {
                fieldName = methodName;
            }
            fieldName = Introspector.decapitalize(fieldName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fieldName;
    }

}

2.3 使用示例

List maps = mongoTemplate.find(Query.query(CriteriaVo.create().isN(User::getNick, "name")), Map.class, "collectionName");

你可能感兴趣的:(模仿mybatisPlus的条件构造器编写mongoDB的条件构造器)