对mybatis-plus中使用Wrappers查询封装

1,050 阅读2分钟

前提

在使用mp中的Wrappers查询中,如果查询的条件多的话,代码就会变得很长,比较难看,而且繁琐,所以在这种情况下对Wrappers进行了一个简单的封装。

封装之前常见使用

// 需要自己拼接查询条件,以及对字段如果不为空进行判断
CommonTask thTask = comTaskService.getOne(Wrappers.lambdaQuery(CommonTask.class)
        .eq(CommonTask::getBusinessId, buniessId)
        .eq(StringUtils.isNotBlank(businessType), CommonTask::getBusinessType, businessType)
        .eq(CommonTask::getTaskState, "运行中")
);

封装后的效果

// 其中taskQueryDto 为查询条件的Dto实体类
QueryWrapper<CommonTask> queryWrapper = WhereBuilder.build(taskQueryDto, new CommonTask());

// 构建出来的queryWrapper 如果还不满足查询可以进行进行添加。
queryWrapper.orderByDesc("create_time");
queryWrapper.eq("is_show", 0);

1、Where.java

创建 Where注解,这个注解用于查询Dto中,进行标注字段使用什么查询条件。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Where {
    // 查询条件
    Condition value() default Condition.eq;
    // 数据库字段名称
    String column();
}

2、Condition.java

查询条件注解,支持如下的条件注解,如果缺少,可以自定义补充。

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public enum Condition {
    eq("eq"),
    ne("ne"),
    lt("lt"),
    le("le"),
    gt("gt"),
    ge("ge"),
    like("like"),
    likeLeft("likeLeft"),
    in("in"),
    likeRight("likeRight");
    private String expression;
}

3、构建自己的查询Dto,例如我这里的

@Data
public class TaskQueryDto {
    @Where(value = Condition.eq, column = "business_id")
    private Integer businessId;

    @Where(value = Condition.eq, column = "business_type")
    private String businessType;

    @Where(value = Condition.in, column = "org_id")
    private List<Integer> orgIds;
}

4、WhereBuilder.java 工具类的封装

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;


@Slf4j
public class WhereBuilder {

    private WhereBuilder() {
    }

    public static <T, R> QueryWrapper<R> build(T t, R r) {
        QueryWrapper<R> queryWrapper = new QueryWrapper();
        if (t == null) return queryWrapper;

        Class<?> tc = t.getClass();
        Stream.of(tc.getDeclaredFields())
                .peek(field -> field.setAccessible(true))
                .filter(field -> {
                    try {
                        if (field.get(t) instanceof String){
                            return StringUtils.isNotBlank((String)field.get(t)) && field.getAnnotation(Where.class) != null;
                        }
                        return field.get(t) != null && field.getAnnotation(Where.class) != null;
                    } catch (IllegalAccessException e) {
                        log.error("获取字段时异常:", e);
                        return false;
                    }
                }).forEach(field -> {
                    try {
                        Where where = field.getAnnotation(Where.class);
                        Condition condition = where.value();
                        String column = where.column();
                        Object value = field.get(t);
                        whereMap.get(condition).invoke(queryWrapper, column, value);
                    } catch (Exception e) {
                        log.error("执行条件拼接时异常:", e);
                    }
                });
        return queryWrapper;
    }

    private static Map<Condition, Con3<QueryWrapper<?>, String, Object>> whereMap = new HashMap<Condition, Con3<QueryWrapper<?>, String, Object>>() {{
        put(Condition.eq, (queryWrapper, column, value) -> queryWrapper = queryWrapper.eq(column, value));
        put(Condition.ne, (queryWrapper, column, value) -> queryWrapper = queryWrapper.ne(column, value));
        put(Condition.lt, (queryWrapper, column, value) -> queryWrapper = queryWrapper.lt(column, value));
        put(Condition.le, (queryWrapper, column, value) -> queryWrapper = queryWrapper.le(column, value));
        put(Condition.gt, (queryWrapper, column, value) -> queryWrapper = queryWrapper.gt(column, value));
        put(Condition.ge, (queryWrapper, column, value) -> queryWrapper = queryWrapper.ge(column, value));
        put(Condition.like, (queryWrapper, column, value) -> queryWrapper = queryWrapper.like(column, value));
        put(Condition.likeLeft, (queryWrapper, column, value) -> queryWrapper = queryWrapper.likeLeft(column, value));
        put(Condition.likeRight, (queryWrapper, column, value) -> queryWrapper = queryWrapper.likeRight(column, value));
        put(Condition.in, (queryWrapper, column, value) -> queryWrapper = queryWrapper.in(column, ((List<Object>)value).toArray()));
    }};
}

@FunctionalInterface
interface Con3<P1, P2, P3> {
    void invoke(P1 p1, P2 p2, P3 p3);
}