美文网首页Mybatis-plus
模仿mybatisPlus的条件构造器编写mongoDB的条件构

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

作者: 任未然 | 来源:发表于2022-04-13 15:55 被阅读0次

一. 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<T, R> extends Function<T, R>, Serializable {
}

2.2 条件构造器

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

public class CriteriaVo extends Criteria{

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

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

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

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

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

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


    public static <T> String columnToString(SFunction<T, ?> 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<Map> maps = mongoTemplate.find(Query.query(CriteriaVo.create().isN(User::getNick, "name")), Map.class, "collectionName");

相关文章

网友评论

    本文标题:模仿mybatisPlus的条件构造器编写mongoDB的条件构

    本文链接:https://www.haomeiwen.com/subject/kosasrtx.html