LambdaWrapper副表添加逻辑删除

This commit is contained in:
yulichang 2022-11-22 16:21:23 +08:00
parent a6eb12bc9e
commit f8ca459519
11 changed files with 121 additions and 212 deletions

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfi
import com.baomidou.mybatisplus.core.injector.AbstractSqlInjector;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.config.InterceptorConfig;
import com.github.yulichang.injector.MPJSqlInjector;
import com.github.yulichang.interceptor.MPJInterceptor;
@ -55,6 +56,7 @@ public class MybatisPlusJoinAutoConfiguration {
public MybatisPlusJoinAutoConfiguration(MybatisPlusJoinProperties properties) {
this.properties = properties;
ConfigProperties.subTableLogic = properties.getSubTableLogic();
}
/**

View File

@ -18,5 +18,10 @@ public class MybatisPlusJoinProperties {
/**
* 打印banner
*/
private Boolean banner = false;
private Boolean banner = true;
/**
* 连表查询副表是否启用逻辑删除(前提是MP配置了逻辑删除)
*/
private Boolean subTableLogic = true;
}

View File

@ -12,6 +12,12 @@
"defaultValue": true,
"type": "java.lang.Boolean",
"description": "打印 banner."
},
{
"name": "mybatis-plus-join.sub-table-logic",
"defaultValue": true,
"type": "java.lang.Boolean",
"description": "连表查询副表是否启用逻辑删除(前提是MP配置了逻辑删除)."
}
]
}

View File

@ -0,0 +1,9 @@
package com.github.yulichang.config;
/**
* @author yulichang
* @since 2.0.0
*/
public class ConfigProperties {
public static boolean subTableLogic = true;
}

View File

@ -315,7 +315,7 @@ public class MPJInterceptor implements Interceptor {
pool.add(columnName);
return columnName;
}
columnName = "mpj_" + StringUtils.getTargetColumn(columnName);
columnName = "join_" + StringUtils.getTargetColumn(columnName);
return getColumn(pool, columnName);
}

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.toolkit.Constant;
import java.util.Objects;
@ -26,6 +27,9 @@ public interface MPJBaseMethod extends Constants {
sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", WRAPPER_ENTITY), true);
sqlScript += NEWLINE;
sqlScript += (NEWLINE + getLogicDeleteSql(table, true, true) + NEWLINE);
if (ConfigProperties.subTableLogic) {
sqlScript += (String.format("${%s.logicSql}", WRAPPER));
}
String normalSqlScript = SqlScriptUtils.convertIf(String.format("AND ${%s}", WRAPPER_SQLSEGMENT), String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_NONEMPTYOFNORMAL), true);
normalSqlScript += NEWLINE;
normalSqlScript += SqlScriptUtils.convertIf(String.format(" ${%s}", WRAPPER_SQLSEGMENT), String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_EMPTYOFNORMAL), true);
@ -37,6 +41,9 @@ public interface MPJBaseMethod extends Constants {
String sqlScript = getAllSqlWhere(table, false, true, WRAPPER_ENTITY_DOT);
sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", WRAPPER_ENTITY), true);
sqlScript += NEWLINE;
if (ConfigProperties.subTableLogic) {
sqlScript += String.format("${%s.logicSql}", WRAPPER);
}
sqlScript += SqlScriptUtils.convertIf(String.format("${%s}", WRAPPER_SQLSEGMENT), String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_NONEMPTYOFWHERE), true);
sqlScript = SqlScriptUtils.convertWhere(sqlScript) + NEWLINE;
sqlScript += SqlScriptUtils.convertIf(String.format(" ${%s}", WRAPPER_SQLSEGMENT), String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_EMPTYOFWHERE), true);

View File

@ -0,0 +1,40 @@
package com.github.yulichang.toolkit;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* 逻辑删除信息类
*
* @author yulichang
* @since 2.0.0
*/
public class LogicInfoUtils implements Constants {
private static final Map<Class<?>, String> LOGIC_CACHE = new ConcurrentHashMap<>();
@SuppressWarnings("ConstantConditions")
public static String getLogicInfo(int tableIndex, Class<?> clazz) {
String logicStr = LOGIC_CACHE.get(clazz);
if (Objects.nonNull(logicStr)) {
return logicStr;
}
TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz);
Assert.notNull(tableInfo, "%s 不是数据库实体或没有注册到mybatis plus中", clazz.getName());
final String value = tableInfo.getLogicDeleteFieldInfo().getLogicNotDeleteValue();
if (NULL.equalsIgnoreCase(value)) {
logicStr = Constant.TABLE_ALIAS + tableIndex + DOT + tableInfo.getLogicDeleteFieldInfo().getColumn() + " IS NULL";
} else {
logicStr = Constant.TABLE_ALIAS + tableIndex + DOT + tableInfo.getLogicDeleteFieldInfo().getColumn() + EQUALS + String.format(tableInfo.getLogicDeleteFieldInfo().isCharSequence() ? "'%s'" : "%s", value);
}
LOGIC_CACHE.put(clazz, logicStr);
return logicStr;
}
}

View File

@ -19,6 +19,7 @@ public final class MPJReflectionKit {
private static final Map<Class<?>, Map<String, Field>> CLASS_FIELD_CACHE = new ConcurrentHashMap<>();
private static final Map<String, Field> EMPTY_MAP = new HashMap<>();
/**
* Collection字段的泛型
@ -48,7 +49,7 @@ public final class MPJReflectionKit {
*/
public static Map<String, Field> getFieldMap(Class<?> clazz) {
if (clazz == null) {
return new HashMap<>();
return EMPTY_MAP;
}
Map<String, Field> fieldMap = CLASS_FIELD_CACHE.get(clazz);
if (fieldMap != null) {

View File

@ -5,11 +5,11 @@ import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.ReflectionKit;
import com.github.yulichang.toolkit.*;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.toolkit.support.SelectColumn;
@ -33,8 +33,6 @@ import java.util.stream.Collectors;
/**
* 参考 {@link com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper}
* Lambda 语法使用 Wrapper
* <p>
* 推荐使用 MPJWrappers.<UserDO>lambdaJoin();构造
*
* @author yulichang
* @see MPJWrappers
@ -301,20 +299,16 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
return typedThis;
}
public <S> MPJLambdaWrapper<T> selectFunc(boolean condition, BaseFuncEnum funcEnum, SFunction<S, ?> column, String alias) {
if (condition) {
public <S> MPJLambdaWrapper<T> selectFunc(BaseFuncEnum funcEnum, SFunction<S, ?> column, String alias) {
ColumnCache cache = getCache(column);
selectColumns.add(SelectColumn.of(LambdaUtils.getEntityClass(column), cache.getColumn(),
cache.getTableFieldInfo(), alias, alias, cache.getKeyType(), false, funcEnum));
}
return typedThis;
}
@Override
public MPJLambdaWrapper<T> selectFunc(boolean condition, BaseFuncEnum funcEnum, Object column, String alias) {
if (condition) {
public MPJLambdaWrapper<T> selectFunc(BaseFuncEnum funcEnum, Object column, String alias) {
selectColumns.add(SelectColumn.of(null, column.toString(), null, alias, alias, null, false, funcEnum));
}
return typedThis;
}
@ -335,7 +329,7 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
*/
@Override
public String getSqlSelect() {
if (StringUtils.isBlank(sqlSelect.getStringValue())) {
if (StringUtils.isBlank(sqlSelect.getStringValue()) && CollectionUtils.isNotEmpty(selectColumns)) {
String s = selectColumns.stream().map(i -> {
String str = Constant.TABLE_ALIAS + getDefault(subTable.get(i.getClazz())) + StringPool.DOT + i.getColumnName();
return (i.getFuncEnum() == null ? str : String.format(i.getFuncEnum().getSql(), str)) +
@ -399,14 +393,26 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
subTable.clear();
}
@Override
public <R> MPJLambdaWrapper<T> join(String keyWord, boolean condition, Class<R> clazz, OnFunction function) {
if (condition) {
MPJLambdaWrapper<?> apply = function.apply(instance(keyWord, clazz));
onWrappers.add(apply);
subTable.put(clazz, tableIndex);
tableIndex++;
/**
* 副表部分逻辑删除支持
*/
public String getLogicSql() {
if (ConfigProperties.subTableLogic) {
if (CollectionUtils.isEmpty(subTable)) {
return StringPool.EMPTY;
}
return "AND " + subTable.entrySet().stream().map(entry ->
LogicInfoUtils.getLogicInfo(entry.getValue(), entry.getKey())).collect(Collectors.joining(" AND "));
}
return StringPool.EMPTY;
}
@Override
public <R> MPJLambdaWrapper<T> join(String keyWord, Class<R> clazz, OnFunction function) {
MPJLambdaWrapper<?> apply = function.apply(instance(keyWord, clazz));
subTable.put(clazz, tableIndex);
onWrappers.add(apply);
tableIndex++;
return typedThis;
}
}

View File

@ -19,7 +19,7 @@ public interface LambdaJoin<Children, Entity> extends MPJBaseJoin<Entity> {
* @param right 条件
*/
default <T, X> Children leftJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
return leftJoin(true, clazz, left, right);
return leftJoin(clazz, on -> on.eq(left, right));
}
/**
@ -27,129 +27,62 @@ public interface LambdaJoin<Children, Entity> extends MPJBaseJoin<Entity> {
* <p>
* leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...)
*
* @param clazz 关联的实体类
* @param function 条件
*/
default <T> Children leftJoin(Class<T> clazz, OnFunction function) {
return leftJoin(true, clazz, function);
}
/**
* left join
*
* @param condition 是否执行
* @param clazz 关联的实体类
* @param left 条件
* @param right 条件
*/
default <T, X> Children leftJoin(boolean condition, Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
return leftJoin(condition, clazz, on -> on.eq(left, right));
}
/**
* left join
* <p>
* leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...)
*
* @param condition 是否执行
* @param clazz 关联实体类
* @param function 条件
*/
default <T> Children leftJoin(boolean condition, Class<T> clazz, OnFunction function) {
return join(Constant.LEFT_JOIN, condition, clazz, function);
default <T> Children leftJoin(Class<T> clazz, OnFunction function) {
return join(Constant.LEFT_JOIN, clazz, function);
}
/**
* ignore 参考 left join
*/
default <T, X> Children rightJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
return rightJoin(true, clazz, left, right);
return rightJoin(clazz, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default <T> Children rightJoin(Class<T> clazz, OnFunction function) {
return rightJoin(true, clazz, function);
}
/**
* ignore 参考 left join
*/
default <T, X> Children rightJoin(boolean condition, Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
return rightJoin(condition, clazz, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default <T> Children rightJoin(boolean condition, Class<T> clazz, OnFunction function) {
return join(Constant.RIGHT_JOIN, condition, clazz, function);
return join(Constant.RIGHT_JOIN, clazz, function);
}
/**
* ignore 参考 left join
*/
default <T, X> Children innerJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
return innerJoin(true, clazz, left, right);
return innerJoin(clazz, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default <T> Children innerJoin(Class<T> clazz, OnFunction function) {
return innerJoin(true, clazz, function);
return join(Constant.INNER_JOIN, clazz, function);
}
/**
* ignore 参考 left join
*/
default <T, X> Children innerJoin(boolean condition, Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
return innerJoin(condition, clazz, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default <T> Children innerJoin(boolean condition, Class<T> clazz, OnFunction function) {
return join(Constant.INNER_JOIN, condition, clazz, function);
}
/**
* ignore 参考 left join
*/
default <T, X> Children fullJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
return fullJoin(true, clazz, left, right);
return fullJoin(clazz, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default <T> Children fullJoin(Class<T> clazz, OnFunction function) {
return fullJoin(true, clazz, function);
}
/**
* ignore 参考 left join
*/
default <T, X> Children fullJoin(boolean condition, Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
return fullJoin(condition, clazz, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default <T> Children fullJoin(boolean condition, Class<T> clazz, OnFunction function) {
return join(Constant.FULL_JOIN, condition, clazz, function);
return join(Constant.FULL_JOIN, clazz, function);
}
/**
* 查询基类 可以直接调用此方法实现以上所有功能
*
* @param keyWord 连表关键字
* @param condition 是否执行
* @param clazz 连表实体类
* @param function 关联条件
*/
<T> Children join(String keyWord, boolean condition, Class<T> clazz, OnFunction function);
<T> Children join(String keyWord, Class<T> clazz, OnFunction function);
}

View File

@ -75,40 +75,20 @@ public interface Query<Children> extends Serializable {
* @param column 函数作用的字段
* @param alias 别名
*/
Children selectFunc(boolean condition, BaseFuncEnum funcEnum, Object column, String alias);
Children selectFunc(BaseFuncEnum funcEnum, Object column, String alias);
<S> Children selectFunc(boolean condition, BaseFuncEnum funcEnum, SFunction<S, ?> column, String alias);
default <S> Children selectFunc(BaseFuncEnum funcEnum, Object column, String alias) {
return selectFunc(true, funcEnum, column, alias);
}
default <S> Children selectFunc(BaseFuncEnum funcEnum, SFunction<S, ?> column, String alias) {
return selectFunc(true, funcEnum, column, alias);
}
<S> Children selectFunc(BaseFuncEnum funcEnum, SFunction<S, ?> column, String alias);
default <S, X> Children selectFunc(BaseFuncEnum funcEnum, SFunction<S, ?> column, SFunction<X, ?> alias) {
return selectFunc(true, funcEnum, column, LambdaUtils.getName(alias));
return selectFunc(funcEnum, column, LambdaUtils.getName(alias));
}
default <S> Children selectFunc(BaseFuncEnum funcEnum, SFunction<S, ?> column) {
return selectFunc(true, funcEnum, column, column);
return selectFunc(funcEnum, column, column);
}
default <X> Children selectFunc(BaseFuncEnum funcEnum, Object column, SFunction<X, ?> alias) {
return selectFunc(true, funcEnum, column, LambdaUtils.getName(alias));
}
default <S, X> Children selectFunc(boolean condition, BaseFuncEnum funcEnum, SFunction<S, ?> column, SFunction<X, ?> alias) {
return selectFunc(condition, funcEnum, column, LambdaUtils.getName(alias));
}
default <S> Children selectFunc(boolean condition, BaseFuncEnum funcEnum, SFunction<S, ?> column) {
return selectFunc(condition, funcEnum, column, column);
}
default <X> Children selectFunc(boolean condition, BaseFuncEnum funcEnum, Object column, SFunction<X, ?> alias) {
return selectFunc(condition, funcEnum, column, LambdaUtils.getName(alias));
return selectFunc(funcEnum, column, LambdaUtils.getName(alias));
}
/**
@ -138,18 +118,6 @@ public interface Query<Children> extends Serializable {
return selectFunc(DefaultFuncEnum.SUM, column, alias);
}
default <S> Children selectSum(boolean condition, SFunction<S, ?> column) {
return selectFunc(condition, DefaultFuncEnum.SUM, column);
}
default <S, X> Children selectSum(boolean condition, SFunction<S, ?> column, SFunction<X, ?> alias) {
return selectFunc(condition, DefaultFuncEnum.SUM, column, alias);
}
default <S, X> Children selectSum(boolean condition, SFunction<S, ?> column, String alias) {
return selectFunc(condition, DefaultFuncEnum.SUM, column, alias);
}
/**
* COUNT()
*/
@ -173,26 +141,6 @@ public interface Query<Children> extends Serializable {
return selectFunc(DefaultFuncEnum.COUNT, column, alias);
}
default <S> Children selectCount(boolean condition, SFunction<S, ?> column) {
return selectFunc(condition, DefaultFuncEnum.COUNT, column);
}
default <X> Children selectCount(boolean condition, Object column, SFunction<X, ?> alias) {
return selectFunc(condition, DefaultFuncEnum.COUNT, column, alias);
}
default Children selectCount(boolean condition, Object column, String alias) {
return selectFunc(condition, DefaultFuncEnum.COUNT, column, alias);
}
default <S, X> Children selectCount(boolean condition, SFunction<S, ?> column, SFunction<X, ?> alias) {
return selectFunc(condition, DefaultFuncEnum.COUNT, column, alias);
}
default <S, X> Children selectCount(boolean condition, SFunction<S, ?> column, String alias) {
return selectFunc(condition, DefaultFuncEnum.COUNT, column, alias);
}
/**
* MAX()
*/
@ -208,18 +156,6 @@ public interface Query<Children> extends Serializable {
return selectFunc(DefaultFuncEnum.MAX, column, alias);
}
default <S> Children selectMax(boolean condition, SFunction<S, ?> column) {
return selectFunc(condition, DefaultFuncEnum.MAX, column);
}
default <S, X> Children selectMax(boolean condition, SFunction<S, ?> column, SFunction<X, ?> alias) {
return selectFunc(condition, DefaultFuncEnum.MAX, column, alias);
}
default <S, X> Children selectMax(boolean condition, SFunction<S, ?> column, String alias) {
return selectFunc(condition, DefaultFuncEnum.MAX, column, alias);
}
/**
* MIN()
*/
@ -235,18 +171,6 @@ public interface Query<Children> extends Serializable {
return selectFunc(DefaultFuncEnum.MIN, column, alias);
}
default <S> Children selectMin(boolean condition, SFunction<S, ?> column) {
return selectFunc(condition, DefaultFuncEnum.MIN, column);
}
default <S, X> Children selectMin(boolean condition, SFunction<S, ?> column, SFunction<X, ?> alias) {
return selectFunc(condition, DefaultFuncEnum.MIN, column, alias);
}
default <S, X> Children selectMin(boolean condition, SFunction<S, ?> column, String alias) {
return selectFunc(condition, DefaultFuncEnum.MIN, column, alias);
}
/**
* MIN()
*/
@ -262,18 +186,6 @@ public interface Query<Children> extends Serializable {
return selectFunc(DefaultFuncEnum.AVG, column, alias);
}
default <S> Children selectAvg(boolean condition, SFunction<S, ?> column) {
return selectFunc(condition, DefaultFuncEnum.AVG, column);
}
default <S, X> Children selectAvg(boolean condition, SFunction<S, ?> column, SFunction<X, ?> alias) {
return selectFunc(condition, DefaultFuncEnum.AVG, column, alias);
}
default <S, X> Children selectAvg(boolean condition, SFunction<S, ?> column, String alias) {
return selectFunc(condition, DefaultFuncEnum.AVG, column, alias);
}
/**
* LEN()
*/
@ -288,16 +200,4 @@ public interface Query<Children> extends Serializable {
default <S, X> Children selectLen(SFunction<S, ?> column, String alias) {
return selectFunc(DefaultFuncEnum.LEN, column, alias);
}
default <S> Children selectLen(boolean condition, SFunction<S, ?> column) {
return selectFunc(condition, DefaultFuncEnum.LEN, column);
}
default <S, X> Children selectLen(boolean condition, SFunction<S, ?> column, SFunction<X, ?> alias) {
return selectFunc(condition, DefaultFuncEnum.LEN, column, alias);
}
default <S, X> Children selectLen(boolean condition, SFunction<S, ?> column, String alias) {
return selectFunc(condition, DefaultFuncEnum.LEN, column, alias);
}
}