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

com.github.yulichang.wrapper.MPJAbstractLambdaWrapper Maven / Gradle / Ivy

There is a newer version: 1.5.2
Show newest version
package com.github.yulichang.wrapper;

import com.baomidou.mybatisplus.annotation.OrderBy;
import com.baomidou.mybatisplus.core.conditions.SharedString;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.config.enums.LogicDelTypeEnum;
import com.github.yulichang.toolkit.*;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.wrapper.enums.PrefixEnum;
import com.github.yulichang.wrapper.interfaces.QueryJoin;
import com.github.yulichang.wrapper.segments.SelectCache;
import lombok.Getter;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.core.enums.WrapperKeyword.APPLY;
import static java.util.stream.Collectors.joining;

/**
 * 参考 {@link com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper}
 *
 * @author yulichang
 */
@SuppressWarnings({"DuplicatedCode", "unused"})
public abstract class MPJAbstractLambdaWrapper>
        extends MPJAbstractWrapper implements QueryJoin {

    /**
     * 主表别名
     */
    protected String alias = ConfigProperties.tableAlias;
    /**
     * 副表别名
     */
    protected String subTableAlias = ConfigProperties.tableAlias;
    /**
     * 是否构建是否存在一对多
     */
    @Getter
    protected boolean resultMap = false;
    /**
     * 表序号
     */
    protected int tableIndex = 1;

    /**
     * 主表 表名处理方法
     */
    protected boolean dynamicTableName = false;

    /**
     * 主表 表名处理方法
     */
    protected Function tableFunc;

    /**
     * 逻辑删除位置
     */
    protected LogicDelTypeEnum logicDelType = ConfigProperties.logicDelType;

    /**
     * 查询表
     */
    protected final SharedString from = new SharedString();
    /**
     * 是否有表别名
     */
    @Getter
    protected boolean hasAlias;
    /**
     * 连表关键字 on 条件 func 使用
     */
    @Getter
    protected String keyWord;
    /**
     * 副表逻辑删除开关
     */
    protected boolean subLogicSql = ConfigProperties.subTableLogic;
    /**
     * 主表逻辑删除开关
     */
    protected boolean logicSql = true;

    /**
     * 推荐使用 带 class 的构造方法
     */
    public MPJAbstractLambdaWrapper() {
        initNeed();
    }

    /**
     * 推荐使用此构造方法
     */
    public MPJAbstractLambdaWrapper(Class clazz) {
        initNeed();
        setEntityClass(clazz);
        tableList.setRootClass(clazz);
    }

    /**
     * 构造方法
     *
     * @param entity 主表实体
     */
    public MPJAbstractLambdaWrapper(T entity) {
        initNeed();
        setEntity(entity);
        if (entity != null) {
            tableList.setRootClass(entity.getClass());
        }
    }

    /**
     * 自定义主表别名
     */
    public MPJAbstractLambdaWrapper(String alias) {
        this.alias = alias;
        initNeed();
        tableList.setAlias(alias);
    }

    /**
     * 构造方法
     *
     * @param clazz 主表class类
     * @param alias 主表别名
     */
    public MPJAbstractLambdaWrapper(Class clazz, String alias) {
        this.alias = alias;
        setEntityClass(clazz);
        initNeed();
        tableList.setAlias(alias);
        tableList.setRootClass(clazz);
    }

    /**
     * 构造方法
     *
     * @param entity 主表实体类
     * @param alias  主表别名
     */
    public MPJAbstractLambdaWrapper(T entity, String alias) {
        this.alias = alias;
        setEntity(entity);
        initNeed();
        tableList.setAlias(alias);
        if (entity != null) {
            tableList.setRootClass(entity.getClass());
        }
    }

    /**
     * 设置表别名
     * 设置表别名注意sql注入问题
     *
     * @return 自定义表别名
     */
    public Children setTableName(Function tableFunc) {
        if (isMain) {
            if (tableFunc != null) {
                this.dynamicTableName = true;
                this.tableFunc = tableFunc;
            }
        } else {
            this.tableName = tableFunc.apply(this.tableName);
        }
        return typedThis;
    }

    public String getTableName(String tableName) {
        if (isMain) {
            if (dynamicTableName) {
                return tableFunc.apply(tableName);
            }
            return tableName;
        }
        return super.getTableName();
    }


    public String getTableNameEnc(String tableName) {
        Class entityClass = getEntityClass();
        if (entityClass != null) {
            TableInfo tableInfo = TableHelper.get(entityClass);
            if (tableInfo != null) {
                if (dynamicTableName) {
                    return tableFunc.apply(tableInfo.getTableName());
                }
                return tableInfo.getTableName();
            }
        }
        String decode;
        try {
            decode = URLDecoder.decode(tableName, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            decode = tableName;
        }
        if (dynamicTableName) {
            return tableFunc.apply(decode);
        }
        return decode;
    }

    @Override
    protected  String columnToString(Integer index, X column, boolean isJoin, PrefixEnum prefixEnum) {
        return columnToString(index, (SFunction) column, isJoin, prefixEnum);
    }

    @Override
    @SafeVarargs
    protected final  String columnsToString(Integer index, boolean isJoin, PrefixEnum prefixEnum, X... columns) {
        return Arrays.stream(columns).map(i -> columnToString(index, (SFunction) i, isJoin, prefixEnum)).collect(joining(StringPool.COMMA));
    }

    protected String columnToString(Integer index, SFunction column, boolean isJoin, PrefixEnum prefixEnum) {
        Class entityClass = LambdaUtils.getEntityClass(column);
        return getDefault(index, entityClass, isJoin, prefixEnum) + StringPool.DOT + getCache(column).getColumn();
    }

    protected SelectCache getCache(SFunction fn) {
        Class aClass = LambdaUtils.getEntityClass(fn);
        Map cacheMap = ColumnCache.getMapField(aClass);
        return cacheMap.get(LambdaUtils.getName(fn));
    }

    /**
     * 返回前缀
     */
    protected String getDefault(Integer index, Class clazz, boolean isJoin, PrefixEnum prefixEnum) {
        if (prefixEnum == PrefixEnum.ON_FIRST) {
            return tableList.getPrefix(index, clazz, false);
        } else if (prefixEnum == PrefixEnum.ON_SECOND) {
            return isJoin ? tableList.getPrefixOther(index, clazz) : tableList.getPrefix(index, clazz, false);
        } else if (prefixEnum == PrefixEnum.CD_FIRST) {
            return tableList.getPrefix(index, clazz, false);
        } else if (prefixEnum == PrefixEnum.CD_SECOND) {
            return isJoin ? tableList.getPrefixOther(index, clazz) :
                    tableList.getPrefix(index, clazz, false);
        } else if (prefixEnum == PrefixEnum.CD_ON_FIRST) {
            return tableList.getPrefix(index, clazz, false);
        } else if (prefixEnum == PrefixEnum.CD_ON_SECOND) {
            return isJoin ? tableList.getPrefixOther(index, clazz) :
                    tableList.getPrefix(index, clazz, false);
        } else {
            return tableList.getAlias();
        }
    }

    /**
     * 关闭副表逻辑删除
     * 

* 副表逻辑删除默认在where语句中 * 但有时候需要让它出现在on语句中, 这两种写法区别还是很大的 * 所以可以关闭副表逻辑删除, 通过on语句多条件, 自己实现on语句的逻辑删除 */ public Children disableSubLogicDel() { this.subLogicSql = false; return typedThis; } public Children enableSubLogicDel() { this.subLogicSql = true; return typedThis; } /** * 关闭主表逻辑删除 */ public Children disableLogicDel() { this.logicSql = false; return typedThis; } public Children enableLogicDel() { this.logicSql = true; return typedThis; } /** * 副表部分逻辑删除支持 */ public String getSubLogicSql() { if (subLogicSql && logicDelType == LogicDelTypeEnum.WHERE) { if (tableList.getAll().isEmpty()) { return StringPool.EMPTY; } return tableList.getAll().stream().map(t -> LogicInfoUtils.getLogicInfo(t.getIndex(), t.getClazz(), t.isHasAlias(), t.getAlias())).collect(Collectors.joining(StringPool.SPACE)); } return StringPool.EMPTY; } /** * 主表部分逻辑删除支持 */ public boolean getLogicSql() { return this.logicSql; } /** * 调整逻辑删除位置为ON语句 */ public Children logicDelToOn() { this.logicDelType = LogicDelTypeEnum.ON; return typedThis; } /** * 调整逻辑删除位置为WHERE语句 */ public Children logicDelToWhere() { this.logicDelType = LogicDelTypeEnum.WHERE; return typedThis; } /** * 获取连表部分语句 */ public String getFrom() { if (StringUtils.isBlank(from.getStringValue())) { StringBuilder value = new StringBuilder(); for (Children wrapper : onWrappers) { if (StringUtils.isBlank(wrapper.from.getStringValue())) { if (wrapper.subLogicSql && this.logicDelType == LogicDelTypeEnum.ON) { TableInfo tableInfo = TableHelper.get(wrapper.getJoinClass()); if (ConfigProperties.tableInfoAdapter.mpjHasLogic(tableInfo)) { wrapper.appendSqlSegments(APPLY, () -> LogicInfoUtils.getLogicInfoNoAnd( wrapper.getIndex(), wrapper.getJoinClass(), wrapper.isHasAlias(), wrapper.getAlias() )); } } value.append(StringPool.SPACE) .append(wrapper.getKeyWord()) .append(StringPool.SPACE) .append(wrapper.getTableName()) .append(StringPool.SPACE) .append(wrapper.hasAlias ? wrapper.alias : (wrapper.alias + wrapper.getIndex())) .append(Constant.ON) .append(wrapper.getExpression().getNormal().getSqlSegment()); } else { value.append(StringPool.SPACE) .append(wrapper.getKeyWord()) .append(StringPool.SPACE) .append(wrapper.from.getStringValue()) .append(StringPool.SPACE); } } from.setStringValue(value.toString()); } return from.getStringValue(); } public String getAlias() { return alias; } /** * 内部调用, 不建议使用 */ @Override public Children join(String keyWord, Class clazz, String tableAlias, BiConsumer, Children> consumer) { Integer oldIndex = this.getIndex(); int newIndex = tableIndex; TableInfo info = TableHelper.get(clazz); Asserts.hasTable(info, clazz); Children instance = instance(newIndex, keyWord, clazz, info.getTableName()); instance.isNo = true; instance.isMain = false; onWrappers.add(instance); if (StringUtils.isBlank(tableAlias)) { tableList.put(oldIndex, clazz, false, subTableAlias, newIndex); instance.alias = subTableAlias; instance.hasAlias = false; } else { tableList.put(oldIndex, clazz, true, tableAlias, newIndex); instance.alias = tableAlias; instance.hasAlias = true; } tableIndex++; this.index = newIndex; boolean isM = this.isMain; this.isMain = false; consumer.accept(instance, typedThis); this.isMain = isM; this.index = oldIndex; return typedThis; } /** * 自定义关键词连接 * * @param keyWord 连表关键词 * @param condition 条件 * @param joinSql sql */ @Override public Children join(String keyWord, boolean condition, String joinSql) { if (condition) { Children wrapper = instanceEmpty(); wrapper.from.setStringValue(joinSql); wrapper.keyWord = keyWord; onWrappers.add(wrapper); } return typedThis; } /** * 是否使用默认注解 {@link OrderBy} 排序 * * @return true 使用 false 不使用 */ public boolean isUseAnnotationOrderBy() { final String _sqlSegment = this.getSqlSegment(); if (StringUtils.isBlank(_sqlSegment)) { return true; } final String _sqlSegmentToUpperCase = _sqlSegment.toUpperCase(); return !(_sqlSegmentToUpperCase.contains(Constants.ORDER_BY) || _sqlSegmentToUpperCase.contains(Constants.LIMIT)); } /** * 必要的初始化 */ protected void initNeed() { paramNameSeq = new AtomicInteger(0); paramNameValuePairs = new HashMap<>(16); expression = new MergeSegments(); lastSql = SharedString.emptyString(); sqlComment = SharedString.emptyString(); sqlFirst = SharedString.emptyString(); tableList = new TableList(); tableList.setAlias(alias); } @Override public void clear() { super.clear(); this.alias = ConfigProperties.tableAlias; this.resultMap = false; this.tableIndex = 1; this.dynamicTableName = false; this.tableFunc = null; this.logicDelType = ConfigProperties.logicDelType; this.from.toNull(); this.hasAlias = false; this.keyWord = null; this.logicSql = true; this.onWrappers.clear(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy