美文网首页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