All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.baomidou.mybatisplus.extension.conditions.query.LambdaJoinQueryWrapper Maven / Gradle / Ivy

/*
 * Copyright (c) 2011-2022, baomidou ([email protected]).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.baomidou.mybatisplus.extension.conditions.query;

import static com.baomidou.mybatisplus.core.enums.SqlKeyword.AND;
import static com.baomidou.mybatisplus.core.enums.SqlKeyword.BETWEEN;
import static com.baomidou.mybatisplus.core.enums.SqlKeyword.NOT_BETWEEN;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.ibatis.reflection.property.PropertyNamer;

import com.baomidou.mybatisplus.core.conditions.AbstractJoinWrapper;
import com.baomidou.mybatisplus.core.conditions.SharedString;
import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.enums.BaseFuncEnum;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.conditions.query.interfaces.JoinCompareFun;
import com.baomidou.mybatisplus.extension.conditions.query.interfaces.LambdaJoinFunc;


/**
 * 本类使用SFunction来构造多表查询条件
 * demo:--需要注意的是 如果要添加其他表的过滤条件或者排序字段,请在调用了join方法后直接调用类似下面这种写法,否则编译不通过
 * LambdaJoinQueryWrapper wrapper = new LambdaJoinQueryWrapper<>(User.class);
 * wrapper.eq(User::getSchoolId,1);
 * wrapper.innerJoin(School.class).like(School::getSchoolName,"一");
 * mapper.selectJoinList(wrapper);
 *
 * @author wanglei
 * @since 2022-03-17
 */
public class LambdaJoinQueryWrapper extends AbstractJoinWrapper,
    LambdaJoinQueryWrapper> implements LambdaJoinFunc, Query, T, SFunction>, JoinCompareFun, T> {

    /**
     * 主表model的class
     */
    private Class mainClass;

    public LambdaJoinQueryWrapper(Class mainClass) {
        super(mainClass);
        this.mainClass = mainClass;
        super.initNeed();
    }


    /**
     * 非对外公开的构造方法,只用于生产嵌套 sql
     *
     * @param entityClass 本不应该需要的
     */
    private LambdaJoinQueryWrapper(Class mainClass, T entity, Class entityClass, AtomicInteger paramNameSeq,
                                   Map paramNameValuePairs, MergeSegments mergeSegments, SharedString paramAlias,
                                   SharedString lastSql, SharedString sqlComment, SharedString sqlFirst, StringBuilder joinFroms,Map, String> aliasMap) {
        super(mainClass);
        super.setEntity(entity);
        super.setEntityClass(entityClass);
        this.mainClass = mainClass;
        this.paramNameSeq = paramNameSeq;
        this.paramNameValuePairs = paramNameValuePairs;
        this.expression = mergeSegments;
        this.paramAlias = paramAlias;
        this.lastSql = lastSql;
        this.sqlComment = sqlComment;
        this.sqlFirst = sqlFirst;
        this.joinFroms = joinFroms;
        this.aliasMap = aliasMap;
    }

    @Override
    protected LambdaJoinQueryWrapper instance() {
        return new LambdaJoinQueryWrapper<>(mainClass, getEntity(), getEntityClass(), paramNameSeq, paramNameValuePairs, new MergeSegments(),
            paramAlias, SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), this.joinFroms,this.aliasMap);
    }

    @Override
    public  LambdaJoinQueryWrapper join(Class joinClass, SFunction leftField, SFunction rightField, String joinType) {
        pubJoin(joinClass, leftField, rightField, joinType);
        return (LambdaJoinQueryWrapper) this;
    }

    public  LambdaJoinQueryWrapper end(Class clz) {
        return (LambdaJoinQueryWrapper) this;
    }

    @Override
    protected  String customBuildJoin(LEFT leftProperty, RIGHT rightProperty) {
        LambdaMeta leftMeta = LambdaUtils.extract((SFunction) leftProperty);
        LambdaMeta rightMeta = LambdaUtils.extract((SFunction) rightProperty);

        // 关联表别名
        String leftAlias = aliasMap.get(leftMeta.getInstantiatedClass());
        // 关联表别名
        String rightAlias = aliasMap.get(rightMeta.getInstantiatedClass());

        getCache(leftMeta.getInstantiatedClass(), PropertyNamer.methodToProperty(leftMeta.getImplMethodName()));

        return Constants.SPACE + leftAlias + Constants.DOT + getCache(leftMeta.getInstantiatedClass(), PropertyNamer.methodToProperty(leftMeta.getImplMethodName())).getColumn()
            + Constants.EQUALS + rightAlias + Constants.DOT + getCache(rightMeta.getInstantiatedClass(), PropertyNamer.methodToProperty(rightMeta.getImplMethodName())).getColumn();
    }

    /**
     * 软删除字段处理
     *
     * @param joinClass
     */
    @Override
    protected void initLogicDelete(Class joinClass, String joinType) {
        TableInfo tableInfo = TableInfoHelper.getTableInfo(joinClass);
        // 不是left join的时候
        if (tableInfo.getLogicDeleteFieldInfo() != null) {
            this.joinFroms.append(Constants.SPACE + Constants.AND + Constants.SPACE + aliasMap.get(joinClass) + Constants.DOT
                + tableInfo.getLogicDeleteFieldInfo().getColumn() + Constants.SPACE + Constants.EQUALS + Constants.SPACE +
                parseLogicNotDeleteValue(tableInfo.getLogicDeleteFieldInfo()));
        }
        //如果没有join其他的表,需要把主表的软删除字段放到on上
        if (this.aliasMap.size() == 2) {
            tableInfo = TableInfoHelper.getTableInfo(this.mainClass);
            if (tableInfo.getLogicDeleteFieldInfo() != null) {
                this.joinFroms.append(Constants.SPACE + Constants.AND + Constants.SPACE + aliasMap.get(this.mainClass) + Constants.DOT
                    + tableInfo.getLogicDeleteFieldInfo().getColumn() + Constants.SPACE + Constants.EQUALS + Constants.SPACE +
                    parseLogicNotDeleteValue(tableInfo.getLogicDeleteFieldInfo()));
            }
        }
    }


    @Override
    public MergeSegments getExpression() {
        //如果没有join其他的表,需要把主表的软删除字段放到where上
        if (this.aliasMap.size() == 1 && !isAppendMainLogicDelete) {
            isAppendMainLogicDelete = true;
            TableInfo tableInfo = TableInfoHelper.getTableInfo(this.mainClass);
            if (tableInfo.getLogicDeleteFieldInfo() != null) {
                eq(LambdaUtils.getSFunction(this.mainClass, tableInfo.getLogicDeleteFieldInfo().getPropertyType()
                        , tableInfo.getLogicDeleteFieldInfo().getProperty())
                    , parseLogicNotDeleteValue(tableInfo.getLogicDeleteFieldInfo()));
            }
        }
        return expression;
    }

    @Override
    protected String columnToString(SFunction column) {
        return extractColumn(column);
    }

    protected String extractColumn(SFunction column) {
        LambdaMeta lambdaMeta = LambdaUtils.extract(column);
        if (!super.aliasMap.containsKey(lambdaMeta.getInstantiatedClass())) {
            throw ExceptionUtils.mpe("not join class: \"%s\".", lambdaMeta.getInstantiatedClass().getName());
        }
        return super.aliasMap.get(lambdaMeta.getInstantiatedClass()) + "." + getCache(lambdaMeta.getInstantiatedClass(),
            PropertyNamer.methodToProperty(lambdaMeta.getImplMethodName())).getColumn();
    }

    @Override
    @SafeVarargs
    public final LambdaJoinQueryWrapper select(SFunction... columns) {
        return select(Arrays.asList(columns));
    }

    public LambdaJoinQueryWrapper select(List> columns) {
        if (CollectionUtils.isNotEmpty(columns)) {
            for (SFunction column : columns) {
                LambdaMeta lambdaMeta = LambdaUtils.extract(column);
                selectColumns.add(SelectColumn.of(lambdaMeta.getInstantiatedClass(), getCache(lambdaMeta.getInstantiatedClass(),
                    PropertyNamer.methodToProperty(lambdaMeta.getImplMethodName())).getColumn()));
            }
        }
        return typedThis;
    }

    /**
     * 查询函数列,如果column不指定,则查询 *
     * 

select xx(column) as alias

*/ @Override public final LambdaJoinQueryWrapper selectFun(BaseFuncEnum fun, SFunction alias, SFunction column) { LambdaMeta aliasLambdaMeta = LambdaUtils.extract(alias); LambdaMeta columnLambdaMeta = column == null ? null : LambdaUtils.extract(column); String columnStr = column == null ? "*" : aliasMap.get(columnLambdaMeta.getInstantiatedClass()) + Constants.DOT + getCache(columnLambdaMeta.getInstantiatedClass(), PropertyNamer.methodToProperty(columnLambdaMeta.getImplMethodName())).getColumn(); String funStr = String.format(fun.getSql(), columnStr); this.funSqlSelect.add(new SharedString(funStr + Constants.AS + PropertyNamer.methodToProperty(aliasLambdaMeta.getImplMethodName()))); return typedThis; } @Override public LambdaJoinQueryWrapper eq(boolean condition, SFunction column, SFunction val) { return addCondition(condition, column, SqlKeyword.EQ, val); } @Override public LambdaJoinQueryWrapper ne(boolean condition, SFunction column, SFunction val) { return addCondition(condition, column, SqlKeyword.NE, val); } @Override public LambdaJoinQueryWrapper gt(boolean condition, SFunction column, SFunction val) { return addCondition(condition, column, SqlKeyword.GT, val); } @Override public LambdaJoinQueryWrapper ge(boolean condition, SFunction column, SFunction val) { return addCondition(condition, column, SqlKeyword.GE, val); } @Override public LambdaJoinQueryWrapper lt(boolean condition, SFunction column, SFunction val) { return addCondition(condition, column, SqlKeyword.LT, val); } @Override public LambdaJoinQueryWrapper le(boolean condition, SFunction column, SFunction val) { return addCondition(condition, column, SqlKeyword.LE, val); } @Override public LambdaJoinQueryWrapper between(boolean condition, SFunction column, SFunction val1, SFunction val2) { return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN, () -> extractColumn(val1), AND, () -> extractColumn(val2))); } @Override public LambdaJoinQueryWrapper notBetween(boolean condition, SFunction column, SFunction val1, SFunction val2) { return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_BETWEEN, () -> extractColumn(val1), AND, () -> extractColumn(val2))); } /** * 普通查询条件 * * @param condition 是否执行 * @param column 属性 * @param sqlKeyword SQL 关键词 * @param val 条件值 */ protected LambdaJoinQueryWrapper addCondition(boolean condition, SFunction column, SqlKeyword sqlKeyword, SFunction val) { return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword, () -> extractColumn(val))); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy