This commit is contained in:
yulichang 2022-11-30 13:49:08 +08:00
parent cb8250ee19
commit f4d82318bc
19 changed files with 311 additions and 195 deletions

View File

@ -14,7 +14,7 @@ public class MappingConfig {
public MappingConfig() {
TableInfoHelper.getTableInfos().forEach(i ->
MPJTableInfoHelper.initTableInfo(i.getEntityType(), MPJTableMapperHelper.get(i.getEntityType())));
MPJTableInfoHelper.initTableInfo(i.getEntityType(), MPJTableMapperHelper.getMapper(i.getEntityType())));
}
}

View File

@ -5,7 +5,9 @@ import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.github.yulichang.interfaces.MPJBaseJoin;
import com.github.yulichang.mapper.MPJTableMapperHelper;
import com.github.yulichang.method.MPJResultType;
import com.github.yulichang.query.MPJQueryWrapper;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.support.SelectColumn;
@ -93,14 +95,26 @@ public class MPJInterceptor implements Interceptor {
/**
* 获取MappedStatement
*/
@SuppressWarnings("rawtypes")
public MappedStatement getMappedStatement(MappedStatement ms, Class<?> resultType, Object ew) {
String id = ms.getId() + StringPool.UNDERSCORE + resultType.getName();
if (ew instanceof MPJLambdaWrapper && ((MPJLambdaWrapper<?>) ew).isResultMap()) {
if (ew instanceof MPJLambdaWrapper) {
MPJLambdaWrapper wrapper = (MPJLambdaWrapper) ew;
wrapper.setEntityClass(MPJTableMapperHelper.getEntity(getEntity(ms.getId())));
//TODO 重构缓存 -> 根据sql缓存
//不走缓存
}
if (ew instanceof MPJQueryWrapper) {
MPJQueryWrapper wrapper = (MPJQueryWrapper) ew;
return getCache(ms, id + wrapper.getSqlSelect(), resultType, ew);
}
return buildMappedStatement(ms, resultType, ew, id);
}
//走缓存
/**
* 走缓存
*/
private MappedStatement getCache(MappedStatement ms, String id, Class<?> resultType, Object ew) {
Map<Configuration, MappedStatement> statementMap = MS_CACHE.get(id);
if (CollectionUtils.isNotEmpty(statementMap)) {
MappedStatement statement = statementMap.get(ms.getConfiguration());
@ -238,7 +252,7 @@ public class MPJInterceptor implements Interceptor {
for (Result r : resultList) {
String columnName = r.getColumn();
//列名去重
columnName = getColumn(columnSet, columnName);
columnName = getColumn(columnSet, StringUtils.getTargetColumn(columnName));
columnList.add(SelectColumn.of(mybatisLabel.getEntityClass(), r.getColumn(), null,
Objects.equals(columnName, r.getColumn()) ? null : columnName, null, null, true, null));
ResultMapping.Builder builder = new ResultMapping.Builder(ms.getConfiguration(), r.getProperty(),
@ -320,7 +334,7 @@ public class MPJInterceptor implements Interceptor {
pool.add(columnName);
return columnName;
}
columnName = "join_" + StringUtils.getTargetColumn(columnName);
columnName = "join_" + columnName;
return getColumn(pool, columnName);
}
@ -339,9 +353,11 @@ public class MPJInterceptor implements Interceptor {
List<ResultMapping> resultMappingList = new ArrayList<>(resultMappings);
//复制不存在的resultMapping
for (Field i : fieldList) {
if (MPJReflectionKit.isPrimitiveOrWrapper(i.getType())) {
resultMappingList.add(new ResultMapping.Builder(ms.getConfiguration(),
i.getName(), i.getName(), i.getType()).build());
}
}
return new ResultMap.Builder(ms.getConfiguration(), id, resultType, resultMappingList).build();
}
}
@ -360,9 +376,17 @@ public class MPJInterceptor implements Interceptor {
/**
* Configuration 添加resultMap
*/
public synchronized static void addResultMap(MappedStatement ms, String key, ResultMap resultMap) {
private synchronized static void addResultMap(MappedStatement ms, String key, ResultMap resultMap) {
if (!ms.getConfiguration().getResultMapNames().contains(key)) {
ms.getConfiguration().addResultMap(resultMap);
}
}
private Class<?> getEntity(String id) {
try {
return Class.forName(id.substring(0, id.lastIndexOf(StringPool.DOT)));
} catch (ClassNotFoundException e) {
return null;
}
}
}

View File

@ -12,14 +12,24 @@ import java.util.concurrent.ConcurrentHashMap;
public class MPJTableMapperHelper {
private static final Map<Class<?>, Class<?>> CACHE = new ConcurrentHashMap<>();
private static final Map<Class<?>, Class<?>> CACHE_REVERSE = new ConcurrentHashMap<>();
public static void init(Class<?> clazz, Class<?> mapper) {
if (clazz != null) {
CACHE.put(clazz, mapper);
}
if (mapper != null) {
CACHE_REVERSE.put(mapper, clazz);
}
}
public static Class<?> get(Class<?> clazz) {
public static Class<?> getMapper(Class<?> clazz) {
return CACHE.get(clazz);
}
public static Class<?> getEntity(Class<?> clazz) {
return CACHE_REVERSE.get(clazz);
}
}

View File

@ -26,9 +26,9 @@ public interface MPJBaseMethod extends Constants {
String sqlScript = getAllSqlWhere(table, true, true, WRAPPER_ENTITY_DOT);
sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", WRAPPER_ENTITY), true);
sqlScript += NEWLINE;
sqlScript += (NEWLINE + getLogicDeleteSql(table, true, true) + NEWLINE);
sqlScript += SqlScriptUtils.convertIf(getLogicDeleteSql(table, true, true), String.format("%s.logicSql", WRAPPER), true);
if (ConfigProperties.subTableLogic) {
sqlScript += (String.format("${%s.logicSql}", WRAPPER));
sqlScript += (NEWLINE + String.format("${%s.subLogicSql}", 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;
@ -42,7 +42,7 @@ public interface MPJBaseMethod extends Constants {
sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", WRAPPER_ENTITY), true);
sqlScript += NEWLINE;
if (ConfigProperties.subTableLogic) {
sqlScript += (String.format("${%s.logicSql}", WRAPPER) + NEWLINE);
sqlScript += (String.format("${%s.subLogicSql}", WRAPPER) + NEWLINE);
}
sqlScript += SqlScriptUtils.convertIf(String.format("AND ${%s}", WRAPPER_SQLSEGMENT), String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_NONEMPTYOFWHERE), true);
sqlScript = SqlScriptUtils.convertWhere(sqlScript) + NEWLINE;

View File

@ -8,6 +8,7 @@ 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.*;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.query.interfaces.MPJJoin;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.MPJWrappers;
@ -60,6 +61,10 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
* 是否 select distinct
*/
private boolean selectDistinct = false;
/**
* 主表逻辑删除
*/
private boolean logicSql = ConfigProperties.subTableLogic;
public MPJQueryWrapper() {
@ -207,10 +212,33 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
/**
* 逻辑删除
*/
public String getLogicSql() {
public String getSubLogicSql() {
return StringPool.EMPTY;
}
/**
* 关闭主表逻辑删除
*/
public MPJQueryWrapper<T> disableLogicDel() {
this.logicSql = false;
return typedThis;
}
/**
* 启用主表逻辑删除
*/
public MPJQueryWrapper<T> enableLogicDel() {
this.logicSql = true;
return typedThis;
}
/**
* 逻辑删除
*/
public boolean getLogicSql() {
return logicSql;
}
/**
* 返回一个支持 lambda 函数写法的 wrapper
*/

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.support.ColumnCache;
import lombok.Getter;
import java.util.Arrays;
import java.util.HashMap;
@ -32,18 +33,19 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
protected Map<Class<?>, Map<String, ColumnCache>> columnMap = new HashMap<>();
@Override
protected <X> String columnToString(X column) {
return columnToString((SFunction<?, ?>) column);
protected <X> String columnToString(X column, boolean isJoin) {
return columnToString((SFunction<?, ?>) column, isJoin);
}
@Override
@SafeVarargs
protected final <X> String columnsToString(X... columns) {
return Arrays.stream(columns).map(i -> columnToString((SFunction<?, ?>) i)).collect(joining(StringPool.COMMA));
protected final <X> String columnsToString(boolean isJoin, X... columns) {
return Arrays.stream(columns).map(i -> columnToString((SFunction<?, ?>) i, isJoin)).collect(joining(StringPool.COMMA));
}
protected String columnToString(SFunction<?, ?> column) {
return Constant.TABLE_ALIAS + getDefault(subTable.get(LambdaUtils.getEntityClass(column))) + StringPool.DOT +
protected String columnToString(SFunction<?, ?> column, boolean isJoin) {
Class<?> entityClass = LambdaUtils.getEntityClass(column);
return Constant.TABLE_ALIAS + getDefault(entityClass, isJoin) + StringPool.DOT +
getCache(column).getColumn();
}
@ -57,9 +59,27 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
return cacheMap.get(LambdaUtils.formatKey(LambdaUtils.getName(fn)));
}
protected String getDefault(Integer i) {
if (Objects.nonNull(i)) {
return i.toString();
protected String getDefault(Class<?> clazz, boolean isJoin) {
Integer index = subTable.get(clazz);
if (Objects.nonNull(index)) {
if (getEntityClass() == null) {
return index.toString();
}
if (isJoin && joinClass == getEntityClass()) {
return StringPool.EMPTY;
}
return index.toString();
}
return StringPool.EMPTY;
}
protected String getDefaultSelect(Class<?> clazz, boolean myself) {
Integer index = subTable.get(clazz);
if (Objects.nonNull(index)) {
if (myself) {
return StringPool.EMPTY;
}
return index.toString();
}
return StringPool.EMPTY;
}

View File

@ -16,6 +16,7 @@ import com.github.yulichang.wrapper.interfaces.Compare;
import com.github.yulichang.wrapper.interfaces.Func;
import com.github.yulichang.wrapper.interfaces.Join;
import com.github.yulichang.wrapper.interfaces.on.OnCompare;
import lombok.Getter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
@ -59,6 +60,10 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
* SQL起始语句
*/
protected SharedString sqlFirst;
/**
* ON sql wrapper集合
*/
protected final List<MPJLambdaWrapper<T>> onWrappers = new ArrayList<>();
/**
* ß
* 数据库表映射实体类
@ -69,6 +74,11 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
* 实体类型(主要用于确定泛型以及取TableInfo缓存)
*/
private Class<T> entityClass;
/**
* 连表实体类 on 条件 func 使用
*/
@Getter
protected Class<?> joinClass;
@Override
public T getEntity() {
@ -89,6 +99,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
public Children setEntityClass(Class<T> entityClass) {
if (entityClass != null) {
onWrappers.forEach(i -> i.setEntityClass(entityClass));
this.entityClass = entityClass;
}
return typedThis;
@ -180,13 +191,13 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
@Override
public <X> Children between(boolean condition, SFunction<X, ?> column, Object val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN,
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), BETWEEN,
() -> formatParam(null, val1), AND, () -> formatParam(null, val2)));
}
@Override
public <X> Children notBetween(boolean condition, SFunction<X, ?> column, Object val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_BETWEEN,
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), NOT_BETWEEN,
() -> formatParam(null, val1), AND, () -> formatParam(null, val2)));
}
@ -258,43 +269,43 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
@Override
public <X> Children isNull(boolean condition, SFunction<X, ?> column) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IS_NULL));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), IS_NULL));
}
@Override
public <X> Children isNotNull(boolean condition, SFunction<X, ?> column) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IS_NOT_NULL));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), IS_NOT_NULL));
}
@Override
public <X> Children in(boolean condition, SFunction<X, ?> column, Collection<?> coll) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IN, inExpression(coll)));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), IN, inExpression(coll)));
}
@Override
public <X> Children in(boolean condition, SFunction<X, ?> column, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IN, inExpression(values)));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), IN, inExpression(values)));
}
@Override
public <X> Children notIn(boolean condition, SFunction<X, ?> column, Collection<?> coll) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_IN, inExpression(coll)));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), NOT_IN, inExpression(coll)));
}
@Override
public <X> Children notIn(boolean condition, SFunction<X, ?> column, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_IN, inExpression(values)));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), NOT_IN, inExpression(values)));
}
@Override
public <X> Children inSql(boolean condition, SFunction<X, ?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IN,
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), IN,
() -> String.format("(%s)", inValue)));
}
@Override
public <X> Children notInSql(boolean condition, SFunction<X, ?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_IN,
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), NOT_IN,
() -> String.format("(%s)", inValue)));
}
@ -302,7 +313,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
public <R> Children groupBy(boolean condition, List<SFunction<R, ?>> columns) {
return maybeDo(condition, () -> {
if (CollectionUtils.isNotEmpty(columns)) {
String one = (StringPool.COMMA + columnsToString(columns));
String one = (StringPool.COMMA + columnsToString(false, columns));
final String finalOne = one;
appendSqlSegments(GROUP_BY, () -> finalOne);
}
@ -312,9 +323,9 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
@Override
public <X> Children groupBy(boolean condition, SFunction<X, ?> column, SFunction<X, ?>... columns) {
return maybeDo(condition, () -> {
String one = columnToString(column);
String one = columnToString(column, false);
if (ArrayUtils.isNotEmpty(columns)) {
one += (StringPool.COMMA + columnsToString(columns));
one += (StringPool.COMMA + columnsToString(false, columns));
}
final String finalOne = one;
appendSqlSegments(GROUP_BY, () -> finalOne);
@ -327,7 +338,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
final SqlKeyword mode = ASC;
if (CollectionUtils.isNotEmpty(columns)) {
columns.forEach(c -> appendSqlSegments(ORDER_BY,
columnToSqlSegment(columnSqlInjectFilter(c)), mode));
columnToSqlSegment(columnSqlInjectFilter(c), false), mode));
}
});
}
@ -338,7 +349,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
final SqlKeyword mode = DESC;
if (CollectionUtils.isNotEmpty(columns)) {
columns.forEach(c -> appendSqlSegments(ORDER_BY,
columnToSqlSegment(columnSqlInjectFilter(c)), mode));
columnToSqlSegment(columnSqlInjectFilter(c), false), mode));
}
});
}
@ -347,10 +358,10 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
public <X> Children orderBy(boolean condition, boolean isAsc, SFunction<X, ?> column, SFunction<X, ?>... columns) {
return maybeDo(condition, () -> {
final SqlKeyword mode = isAsc ? ASC : DESC;
appendSqlSegments(ORDER_BY, columnToSqlSegment(column), mode);
appendSqlSegments(ORDER_BY, columnToSqlSegment(column, false), mode);
if (ArrayUtils.isNotEmpty(columns)) {
Arrays.stream(columns).forEach(c -> appendSqlSegments(ORDER_BY,
columnToSqlSegment(columnSqlInjectFilter(c)), mode));
columnToSqlSegment(columnSqlInjectFilter(c), false), mode));
}
});
}
@ -397,7 +408,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
* <p>拼接 LIKE 以及 </p>
*/
protected <X> Children likeValue(boolean condition, SqlKeyword keyword, SFunction<X, ?> column, Object val, SqlLike sqlLike) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), keyword,
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), keyword,
() -> formatParam(null, SqlUtils.concatLike(val, sqlLike))));
}
@ -410,13 +421,13 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
* @param val 条件值
*/
protected <X> Children addCondition(boolean condition, SFunction<X, ?> column, SqlKeyword sqlKeyword, Object val) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword,
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, true), sqlKeyword,
() -> formatParam(null, val)));
}
protected <X, S> Children addCondition(boolean condition, SFunction<X, ?> column, SqlKeyword sqlKeyword, SFunction<S, ?> val) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword,
columnToSqlSegment(val)));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), sqlKeyword,
columnToSqlSegment(val, true)));
}
/**
@ -598,14 +609,14 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
/**
* 获取 columnName
*/
protected final <X> ISqlSegment columnToSqlSegment(SFunction<X, ?> column) {
return () -> columnToString(column);
protected final <X> ISqlSegment columnToSqlSegment(SFunction<X, ?> column, boolean isJoin) {
return () -> columnToString(column, isJoin);
}
/**
* 获取 columnName
*/
protected <X> String columnToString(X column) {
protected <X> String columnToString(X column, boolean isJoin) {
return (String) column;
}
@ -614,8 +625,8 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
*
* @param columns 多字段
*/
protected <X> String columnsToString(X... columns) {
return Arrays.stream(columns).map(this::columnToString).collect(joining(StringPool.COMMA));
protected <X> String columnsToString(boolean isJoin, X... columns) {
return Arrays.stream(columns).map(i -> this.columnToString(i, isJoin)).collect(joining(StringPool.COMMA));
}
@Override
@ -667,33 +678,33 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
@Override
public <R, S, U> Children between(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val1, SFunction<U, ?> val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN,
columnToSqlSegment(val1), AND, columnToSqlSegment(val2)));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), BETWEEN,
columnToSqlSegment(val1, true), AND, columnToSqlSegment(val2, true)));
}
public <R, S> Children between(boolean condition, SFunction<R, ?> column, Object val1, SFunction<S, ?> val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN,
() -> formatParam(null, val1), AND, columnToSqlSegment(val2)));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), BETWEEN,
() -> formatParam(null, val1), AND, columnToSqlSegment(val2, true)));
}
public <R, S> Children between(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN,
columnToSqlSegment(val1), AND, () -> formatParam(null, val2)));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), BETWEEN,
columnToSqlSegment(val1, true), AND, () -> formatParam(null, val2)));
}
@Override
public <R, S, U> Children notBetween(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val1, SFunction<U, ?> val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_BETWEEN,
columnToSqlSegment(val1), AND, columnToSqlSegment(val2)));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), NOT_BETWEEN,
columnToSqlSegment(val1, true), AND, columnToSqlSegment(val2, true)));
}
public <R, U> Children notBetween(boolean condition, SFunction<R, ?> column, Object val1, SFunction<U, ?> val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_BETWEEN,
() -> formatParam(null, val1), AND, columnToSqlSegment(val2)));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), NOT_BETWEEN,
() -> formatParam(null, val1), AND, columnToSqlSegment(val2, true)));
}
public <R, S> Children notBetween(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_BETWEEN,
columnToSqlSegment(val1), AND, () -> formatParam(null, val2)));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), NOT_BETWEEN,
columnToSqlSegment(val1, true), AND, () -> formatParam(null, val2)));
}
}

View File

@ -54,10 +54,6 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
*/
@Getter
private final List<SelectColumn> selectColumns = new ArrayList<>();
/**
* ON sql wrapper集合
*/
private final List<MPJLambdaWrapper<?>> onWrappers = new ArrayList<>();
/**
* 映射关系
*/
@ -68,6 +64,11 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
*/
@Getter
private boolean resultMap = false;
/**
* 是否自定义resultMap 自动构建不算
*/
@Getter
private boolean customResult = false;
/**
* 查询字段 sql
*/
@ -85,12 +86,14 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
*/
@Getter
private String keyWord;
/**
* 连表实体类 on 条件 func 使用
* 副表逻辑删除开关
*/
@Getter
private Class<?> joinClass;
private boolean subLogicSql = ConfigProperties.subTableLogic;
/**
* 主表逻辑删除开关
*/
private boolean logicSql = true;
/**
* 不建议直接 new 该实例使用 MPJWrappers.<UserDO>lambdaQuery()
@ -225,7 +228,9 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
Class<?> genericType = MPJReflectionKit.getGenericType(field);
Class<Z> ofType = (Class<Z>) genericType;
MybatisLabel.Builder<C, Z> builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), ofType, false);
this.resultMapMybatisLabel.add(collection.apply(builder).build());
MybatisLabel.Builder<C, Z> czBuilder = collection.apply(builder);
this.customResult = czBuilder.hasCustom();
this.resultMapMybatisLabel.add(czBuilder.build());
return typedThis;
}
@ -260,7 +265,9 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
this.resultMap = true;
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabel.Builder<C, F> builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), (Class<F>) child, false);
this.resultMapMybatisLabel.add(collection.apply(builder).build());
MybatisLabel.Builder<C, F> cfBuilder = collection.apply(builder);
this.customResult = cfBuilder.hasCustom();
this.resultMapMybatisLabel.add(cfBuilder.build());
return typedThis;
}
@ -331,7 +338,7 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
public String getSqlSelect() {
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();
String str = Constant.TABLE_ALIAS + getDefaultSelect(i.getClazz(), (i.getClazz() == getEntityClass() && !i.isLabel())) + StringPool.DOT + i.getColumnName();
return (i.getFuncEnum() == null ? str : String.format(i.getFuncEnum().getSql(), str)) +
(StringUtils.isBlank(i.getAlias()) ? StringPool.EMPTY : (Constant.AS + i.getAlias()));
}).collect(Collectors.joining(StringPool.COMMA));
@ -393,11 +400,41 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
subTable.clear();
}
/**
* 关闭副表逻辑删除
* <p>
* 副表逻辑删除默认在where语句中
* 但有时候需要让它出现在on语句中, 这两种写法区别还是很大的
* 所以可以关闭副表逻辑删除, 通过on语句多条件, 自己实现on语句的逻辑删除
*/
public MPJLambdaWrapper<T> disableSubLogicDel() {
this.subLogicSql = false;
return typedThis;
}
public MPJLambdaWrapper<T> enableSubLogicDel() {
this.subLogicSql = true;
return typedThis;
}
/**
* 关闭主表逻辑删除
*/
public MPJLambdaWrapper<T> disableLogicDel() {
this.logicSql = false;
return typedThis;
}
public MPJLambdaWrapper<T> enableLogicDel() {
this.logicSql = true;
return typedThis;
}
/**
* 副表部分逻辑删除支持
*/
public String getLogicSql() {
if (ConfigProperties.subTableLogic) {
public String getSubLogicSql() {
if (subLogicSql) {
if (CollectionUtils.isEmpty(subTable)) {
return StringPool.EMPTY;
}
@ -407,9 +444,16 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
return StringPool.EMPTY;
}
/**
* 主表部分逻辑删除支持
*/
public boolean getLogicSql() {
return this.logicSql;
}
@Override
public <R> MPJLambdaWrapper<T> join(String keyWord, Class<R> clazz, OnFunction function) {
MPJLambdaWrapper<?> apply = function.apply(instance(keyWord, clazz));
public <R> MPJLambdaWrapper<T> join(String keyWord, Class<R> clazz, OnFunction<T> function) {
MPJLambdaWrapper<T> apply = function.apply(instance(keyWord, clazz));
subTable.put(clazz, tableIndex);
onWrappers.add(apply);
tableIndex++;

View File

@ -23,14 +23,14 @@ public interface LambdaJoin<Children, Entity> extends MPJBaseJoin<Entity> {
}
/**
* left join
* left join 多条件
* <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) {
default <T> Children leftJoin(Class<T> clazz, OnFunction<Entity> function) {
return join(Constant.LEFT_JOIN, clazz, function);
}
@ -44,7 +44,7 @@ public interface LambdaJoin<Children, Entity> extends MPJBaseJoin<Entity> {
/**
* ignore 参考 left join
*/
default <T> Children rightJoin(Class<T> clazz, OnFunction function) {
default <T> Children rightJoin(Class<T> clazz, OnFunction<Entity> function) {
return join(Constant.RIGHT_JOIN, clazz, function);
}
@ -58,7 +58,7 @@ public interface LambdaJoin<Children, Entity> extends MPJBaseJoin<Entity> {
/**
* ignore 参考 left join
*/
default <T> Children innerJoin(Class<T> clazz, OnFunction function) {
default <T> Children innerJoin(Class<T> clazz, OnFunction<Entity> function) {
return join(Constant.INNER_JOIN, clazz, function);
}
@ -73,7 +73,7 @@ public interface LambdaJoin<Children, Entity> extends MPJBaseJoin<Entity> {
/**
* ignore 参考 left join
*/
default <T> Children fullJoin(Class<T> clazz, OnFunction function) {
default <T> Children fullJoin(Class<T> clazz, OnFunction<Entity> function) {
return join(Constant.FULL_JOIN, clazz, function);
}
@ -84,5 +84,5 @@ public interface LambdaJoin<Children, Entity> extends MPJBaseJoin<Entity> {
* @param clazz 连表实体类
* @param function 关联条件
*/
<T> Children join(String keyWord, Class<T> clazz, OnFunction function);
<T> Children join(String keyWord, Class<T> clazz, OnFunction<Entity> function);
}

View File

@ -9,7 +9,7 @@ import com.github.yulichang.wrapper.MPJLambdaWrapper;
* @since 1.1.8
*/
@FunctionalInterface
public interface OnFunction {
public interface OnFunction<T> {
MPJLambdaWrapper<?> apply(MPJLambdaWrapper<?> wrapper);
MPJLambdaWrapper<T> apply(MPJLambdaWrapper<T> wrapper);
}

View File

@ -178,6 +178,9 @@ public class MybatisLabel<E, T> {
return this;
}
public boolean hasCustom(){
return CollectionUtils.isNotEmpty(mybatisLabel.resultList) || CollectionUtils.isNotEmpty(mybatisLabel.mybatisLabels);
}
public MybatisLabel<E, T> build() {
if (CollectionUtils.isEmpty(mybatisLabel.resultList)) {

View File

@ -0,0 +1,5 @@
## mybatis plus join 测试模块
- test-collection : 对多或对一查询测试工程
- test-join : 连表查询测试类
- test-mapping : 注解映射测试工程

View File

@ -1,24 +0,0 @@
package com.github.yulichang.test.collection.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;
import lombok.ToString;
@Getter
@ToString
public enum Sex {
MAN(0, ""),
WOMAN(1, "");
@EnumValue
private final int code;
private final String des;
Sex(int code, String des) {
this.code = code;
this.des = des;
}
}

View File

@ -1,61 +0,0 @@
package com.github.yulichang.test.join.dto;
import lombok.Data;
import java.util.List;
@Data
public class TableDTO {
private Integer id;
private String name;
private List<TableBDTO> bbList;
@Data
public static class TableBDTO {
private Integer id;
private Integer aid;
private String name;
private List<TableCDTO> ccList;
}
@Data
public static class TableCDTO {
private Integer id;
private Integer bid;
private String name;
private List<TableDDTO> ddList;
}
@Data
public static class TableDDTO {
private Integer id;
private Integer cid;
private String name;
private List<TableEDTO> eeList;
}
@Data
public static class TableEDTO {
private Integer id;
private Integer did;
private String name;
}
}

View File

@ -1,5 +1,6 @@
package com.github.yulichang.test.join.dto;
import com.github.yulichang.test.join.entity.UserDO;
import com.github.yulichang.test.join.enums.Sex;
import lombok.Data;
import lombok.ToString;
@ -35,7 +36,9 @@ public class UserDTO {
/** area */
private String city;
/** area */
private String area;
private Map<String, String> area;
private List<AddressDTO> addressList;
private List<UserDO> children;
}

View File

@ -11,20 +11,23 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.List;
import java.util.Map;
@Data
@ToString
@Accessors(chain = true)
@EqualsAndHashCode
@TableName(value = "`user`",autoResultMap = true)
@TableName(value = "`user`", autoResultMap = true)
public class UserDO {
@TableId
private Integer id;
private Integer pid;
@TableField(value = "`name`", typeHandler = JacksonTypeHandler.class)
private Map<String,String> aName;
private Map<String, String> name;
private Sex sex;
@ -34,4 +37,7 @@ public class UserDO {
@TableLogic
private Boolean del;
@TableField(exist = false)
private List<UserDO> children;
}

View File

@ -29,28 +29,28 @@ INSERT INTO area (id, province, city, area, postcode, del) VALUES (10022, '北
DELETE FROM `user`;
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES ( 1, '{"aa":"aaa","bb":"bbb"}', 1, 1, 'https://url-01', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES ( 2, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-02', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES ( 3, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-03', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES ( 4, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-04', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES ( 5, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-05', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES ( 6, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-06', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES ( 7, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-07', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES ( 8, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-08', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES ( 9, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-09', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES (10, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-10', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES (11, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-11', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES (12, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-12', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES (13, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-13', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES (14, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-14', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES (15, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-15', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES (16, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-16', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES (17, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-17', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES (18, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-18', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES (19, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-19', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES (20, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-20', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES (21, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-21', false);
INSERT INTO `user` (id, `name`, `address_id`, sex, head_img, del) VALUES (22, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-22', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 1, 1, '{"aa":"aaa","bb":"bbb"}', 1, 1, 'https://url-01', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 2, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-02', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 3, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-03', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 4, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-04', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 5, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-05', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 6, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-06', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 7, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-07', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 8, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-08', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES ( 9, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-09', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (10, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-10', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (11, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-11', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (12, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-12', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (13, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-13', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (14, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-14', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (15, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-15', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (16, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-16', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (17, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-17', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (18, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-18', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (19, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-19', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (20, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-20', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (21, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-21', false);
INSERT INTO `user` (id, pid, `name`, `address_id`, sex, head_img, del) VALUES (22, 1, '{"aa":"aaa","bb":"bbb"}', 1, 0, 'https://url-22', false);
DELETE FROM address;

View File

@ -21,6 +21,7 @@ create table `user`
(
id int auto_increment
primary key,
`pid` int not null,
`name` varchar(255) not null,
`address_id` int not null,
sex tinyint not null,

View File

@ -8,6 +8,7 @@ import com.github.yulichang.test.join.dto.UserDTO;
import com.github.yulichang.test.join.entity.AddressDO;
import com.github.yulichang.test.join.entity.AreaDO;
import com.github.yulichang.test.join.entity.UserDO;
import com.github.yulichang.test.join.mapper.AddressMapper;
import com.github.yulichang.test.join.mapper.UserMapper;
import com.github.yulichang.toolkit.MPJWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
@ -59,6 +60,51 @@ class LambdaWrapperTest {
System.out.println(list);
}
/**
* ms缓存测试
*/
@Test
void testMSCache() {
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.selectAll(UserDO.class)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.leftJoin(AreaDO.class, AreaDO::getId, AddressDO::getAreaId);
List<UserDTO> list = userMapper.selectJoinList(UserDTO.class, wrapper);
MPJLambdaWrapper<UserDO> wrapper1 = new MPJLambdaWrapper<UserDO>()
.select(UserDO::getId)
.selectAs(UserDO::getName,UserDTO::getArea)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.leftJoin(AreaDO.class, AreaDO::getId, AddressDO::getAreaId);
List<UserDTO> list1 = userMapper.selectJoinList(UserDTO.class, wrapper1);
assert list1.get(0).getArea() != null;
}
/**
* 自连接测试
*/
@Test
void testInner() throws Exception {
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.disableSubLogicDel()
.disableLogicDel()
.selectAll(UserDO.class)
.selectCollection(UserDO.class, UserDO::getChildren)
.leftJoin(UserDO.class, UserDO::getPid, UserDO::getId);
List<UserDO> list = userMapper.selectJoinList(UserDO.class, wrapper);
MPJLambdaWrapper<UserDO> wrapper1 = new MPJLambdaWrapper<UserDO>()
.disableSubLogicDel()
.disableLogicDel()
.selectAll(UserDO.class)
.selectCollection(UserDO.class, UserDO::getChildren)
.leftJoin(UserDO.class, UserDO::getPid, UserDO::getId);
List<UserDO> list1 = userMapper.selectJoinList(UserDO.class, wrapper1);
System.out.println(list);
}
/**
* 简单的分页关联查询 lambda