join嵌套

This commit is contained in:
yulichang 2022-12-15 19:06:15 +08:00
parent b31e271a37
commit 917a400290
18 changed files with 260 additions and 126 deletions

View File

@ -57,6 +57,7 @@ public class MybatisPlusJoinAutoConfiguration {
public MybatisPlusJoinAutoConfiguration(MybatisPlusJoinProperties properties) {
this.properties = properties;
ConfigProperties.subTableLogic = properties.getSubTableLogic();
ConfigProperties.msCache = properties.isMsCache();
}
/**

View File

@ -24,4 +24,9 @@ public class MybatisPlusJoinProperties {
* 连表查询副表是否启用逻辑删除(前提是MP配置了逻辑删除)
*/
private Boolean subTableLogic = true;
/**
* MappedStatement缓存
*/
private boolean msCache = true;
}

View File

@ -18,6 +18,12 @@
"defaultValue": true,
"type": "java.lang.Boolean",
"description": "连表查询副表是否启用逻辑删除(前提是MP配置了逻辑删除)."
},
{
"name": "mybatis-plus-join.ms-cache",
"defaultValue": true,
"type": "java.lang.Boolean",
"description": "MappedStatement缓存开关."
}
]
}

View File

@ -6,4 +6,5 @@ package com.github.yulichang.config;
*/
public class ConfigProperties {
public static boolean subTableLogic = true;
public static boolean msCache = true;
}

View File

@ -3,6 +3,7 @@ package com.github.yulichang.interceptor;
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.mapper.MPJTableMapperHelper;
import com.github.yulichang.method.MPJResultType;
import com.github.yulichang.query.MPJQueryWrapper;
@ -92,7 +93,9 @@ public class MPJInterceptor implements Interceptor {
}
if (ew instanceof MPJQueryWrapper) {
MPJQueryWrapper wrapper = (MPJQueryWrapper) ew;
return getCache(ms, id + StringPool.UNDERSCORE + wrapper.getSqlSelect(), resultType, ew);
if (ConfigProperties.msCache) {
return getCache(ms, id + StringPool.UNDERSCORE + wrapper.getSqlSelect(), resultType, ew);
}
}
return buildMappedStatement(ms, resultType, ew, id);
}

View File

@ -32,19 +32,19 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
@Override
protected <X> String columnToString(String index, X column, boolean isJoin) {
return columnToString(index, (SFunction<?, ?>) column, isJoin);
protected <X> String columnToString(String index, int node, X column, boolean isJoin) {
return columnToString(index, node, (SFunction<?, ?>) column, isJoin);
}
@Override
@SafeVarargs
protected final <X> String columnsToString(String index, boolean isJoin, X... columns) {
return Arrays.stream(columns).map(i -> columnToString(index, (SFunction<?, ?>) i, isJoin)).collect(joining(StringPool.COMMA));
protected final <X> String columnsToString(String index, int node, boolean isJoin, X... columns) {
return Arrays.stream(columns).map(i -> columnToString(index, node, (SFunction<?, ?>) i, isJoin)).collect(joining(StringPool.COMMA));
}
protected String columnToString(String index, SFunction<?, ?> column, boolean isJoin) {
protected String columnToString(String index, int node, SFunction<?, ?> column, boolean isJoin) {
Class<?> entityClass = LambdaUtils.getEntityClass(column);
return Constant.TABLE_ALIAS + getDefault(index, entityClass, isJoin) + StringPool.DOT +
return Constant.TABLE_ALIAS + getDefault(index, node, entityClass, isJoin) + StringPool.DOT +
getCache(column).getTagColumn();
}
@ -54,9 +54,9 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
return cacheMap.get(LambdaUtils.getName(fn));
}
protected String getDefault(String index, Class<?> clazz, boolean isJoin) {
protected String getDefault(String index, int node, Class<?> clazz, boolean isJoin) {
if (Objects.isNull(index)) {
if (Objects.equals(clazz, getEntityClass())) {
if (!isJoin && Objects.equals(clazz, getEntityClass())) {
return StringPool.EMPTY;
}
//正序
@ -66,12 +66,18 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
Table table = tableList.get(clazz, index);
if (Objects.nonNull(table.getIndex())) {
if (isJoin && clazz == getEntityClass()) {
//除自己以外的倒序第一个
Table t = tableList.getOrElse(clazz, index);
if (Objects.isNull(t.getIndex())) {
if (node == -1) {
return StringPool.EMPTY;
} else if (node == 0) {
//除自己以外的倒序第一个
Table t = tableList.getOrElse(clazz, index);
if (Objects.isNull(t.getIndex())) {
return StringPool.EMPTY;
}
return t.getIndex();
} else {
return String.valueOf(node);
}
return t.getIndex();
}
return table.getIndex();
}

View File

@ -15,7 +15,9 @@ import com.github.yulichang.toolkit.sql.SqlScriptUtils;
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 com.github.yulichang.wrapper.interfaces.OnCompare;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import java.util.*;
@ -37,6 +39,8 @@ import static java.util.stream.Collectors.joining;
public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<T, Children>> extends Wrapper<T>
implements Compare<Children>, Nested<Children, Children>, Join<Children>, Func<Children>, OnCompare<Children> {
protected static final Node ROOT_NODE = new Node(null, 0, null);
/**
* 占位符
*/
@ -85,6 +89,11 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
@Getter
protected Class<?> joinClass;
/**
* 寻路
*/
protected Node node;
@Override
public T getEntity() {
return entity;
@ -318,7 +327,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(index, false, columns));
String one = (StringPool.COMMA + columnsToString(index, getByClass(node, joinClass), false, columns));
final String finalOne = one;
appendSqlSegments(GROUP_BY, () -> finalOne);
}
@ -328,9 +337,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(index, column, false);
String one = columnToString(index, getByClass(node, joinClass), column, false);
if (ArrayUtils.isNotEmpty(columns)) {
one += (StringPool.COMMA + columnsToString(index, false, columns));
one += (StringPool.COMMA + columnsToString(index, getByClass(node, joinClass), false, columns));
}
final String finalOne = one;
appendSqlSegments(GROUP_BY, () -> finalOne);
@ -431,6 +440,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
}
protected <X, S> Children addCondition(boolean condition, SFunction<X, ?> column, SqlKeyword sqlKeyword, SFunction<S, ?> val) {
Node nnnn = this.node;
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), sqlKeyword,
columnToSqlSegment(index, val, true)));
}
@ -541,6 +551,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
lastSql = SharedString.emptyString();
sqlComment = SharedString.emptyString();
sqlFirst = SharedString.emptyString();
node = ROOT_NODE;
}
@Override
@ -615,13 +626,13 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
* 获取 columnName
*/
protected final <X> ISqlSegment columnToSqlSegment(String index, SFunction<X, ?> column, boolean isJoin) {
return () -> columnToString(index, column, isJoin);
return () -> columnToString(index, getByClass(node, joinClass), column, isJoin);
}
/**
* 获取 columnName
*/
protected <X> String columnToString(String index, X column, boolean isJoin) {
protected <X> String columnToString(String index, int node, X column, boolean isJoin) {
return (String) column;
}
@ -630,8 +641,8 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
*
* @param columns 多字段
*/
protected <X> String columnsToString(String index, boolean isJoin, X... columns) {
return Arrays.stream(columns).map(i -> this.columnToString(index, i, isJoin)).collect(joining(StringPool.COMMA));
protected <X> String columnsToString(String index, int node, boolean isJoin, X... columns) {
return Arrays.stream(columns).map(i -> this.columnToString(index, node, i, isJoin)).collect(joining(StringPool.COMMA));
}
@Override
@ -680,4 +691,38 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
public <R, S> Children le(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val) {
return addCondition(condition, column, LE, val);
}
@Data
@AllArgsConstructor
public static class Node {
private Class<?> clazz;
private int index;
private Node parent;
}
private int getByClass(Node node, Class<?> joinClass) {
if (joinClass == null) {
return 0;
}
if (node.parent != null) {
return dg(node.parent, joinClass);
}
return 0;
}
private int dg(Node node, Class<?> joinClass) {
if (node.clazz != null && node.clazz == joinClass) {
return node.index;
}
if (node.parent == null) {
return joinClass == getEntityClass() ? -1 : 0;
}
return getByClass(node.parent, joinClass);
}
}

View File

@ -17,7 +17,7 @@ import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.wrapper.interfaces.Query;
import com.github.yulichang.wrapper.interfaces.QueryJoin;
import com.github.yulichang.wrapper.interfaces.QueryLabel;
import com.github.yulichang.wrapper.interfaces.on.WrapperFunction;
import com.github.yulichang.wrapper.interfaces.WrapperBiConsumer;
import com.github.yulichang.wrapper.resultmap.MybatisLabel;
import com.github.yulichang.wrapper.segments.Select;
import com.github.yulichang.wrapper.segments.SelectCache;
@ -92,12 +92,20 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
private boolean logicSql = true;
/**
* 不建议直接 new 该实例使用 MPJWrappers.<UserDO>lambdaQuery()
* 推荐使用 class 的构造方法
*/
public MPJLambdaWrapper() {
super.initNeed();
}
/**
* 推荐使用此构造方法
*/
public MPJLambdaWrapper(Class<T> clazz) {
super.initNeed();
setEntityClass(clazz);
}
/**
* 不建议直接 new 该实例使用 MPJWrappers.<UserDO>lambdaQuery()
@ -105,7 +113,7 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
MPJLambdaWrapper(T entity, Class<T> entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq,
Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments,
SharedString lastSql, SharedString sqlComment, SharedString sqlFirst,
TableList tableList, String index, String keyWord, Class<?> joinClass) {
TableList tableList, String index, String keyWord, Class<?> joinClass, Node node) {
super.setEntity(entity);
super.setEntityClass(entityClass);
this.paramNameSeq = paramNameSeq;
@ -119,6 +127,7 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
this.index = index;
this.keyWord = keyWord;
this.joinClass = joinClass;
this.node = node;
}
@ -220,13 +229,13 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
*/
@Override
protected MPJLambdaWrapper<T> instance() {
return instance(index, null, null);
return instance(index, null, null, this.node);
}
protected MPJLambdaWrapper<T> instance(String index, String keyWord, Class<?> joinClass) {
protected MPJLambdaWrapper<T> instance(String index, String keyWord, Class<?> joinClass, Node node) {
return new MPJLambdaWrapper<>(getEntity(), getEntityClass(), null, paramNameSeq, paramNameValuePairs,
new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
this.tableList, index, keyWord, joinClass);
this.tableList, index, keyWord, joinClass, node);
}
@Override
@ -293,17 +302,19 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
* 调用此方法 keyword 前后需要带空格 比如 " LEFT JOIN " " RIGHT JOIN "
*/
@Override
public <R> MPJLambdaWrapper<T> join(String keyWord, Class<R> clazz, WrapperFunction<T> function, WrapperFunction<T> ext) {
String name = String.valueOf(tableIndex);
MPJLambdaWrapper<T> apply = function.apply(instance(name, keyWord, clazz));
tableList.add(clazz, name);
onWrappers.add(apply);
public <R> MPJLambdaWrapper<T> join(String keyWord, Class<R> clazz, WrapperBiConsumer<T> consumer) {
Node nnnnn = this.node;
String oldIndex = this.getIndex();
String newIndex = String.valueOf(tableIndex);
Node n = Objects.isNull(oldIndex) ? new Node(clazz, tableIndex, ROOT_NODE) : new Node(clazz, tableIndex, this.node);
MPJLambdaWrapper<T> instance = instance(newIndex, keyWord, clazz, n);
this.node = n;
tableList.add(clazz, newIndex);
onWrappers.add(instance);
tableIndex++;
if (Objects.nonNull(ext)) {
this.index = name;
MPJLambdaWrapper<T> wrapper = ext.apply(typedThis);
wrapper.index = null;
}
this.index = newIndex;
consumer.accept(instance, typedThis);
this.index = oldIndex;
return typedThis;
}
}

View File

@ -1,4 +1,4 @@
package com.github.yulichang.wrapper.interfaces.on;
package com.github.yulichang.wrapper.interfaces;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;

View File

@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.interfaces.MPJBaseJoin;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.wrapper.interfaces.on.WrapperFunction;
/**
* @author yulichang
@ -20,7 +19,7 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
* @param right 条件
*/
default <T, X> Children leftJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
return leftJoin(clazz, on -> on.eq(left, right));
return join(Constant.LEFT_JOIN, clazz, left, right);
}
/**
@ -30,7 +29,7 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
* @param right 条件
*/
default <T, X> Children leftJoin(SFunction<T, ?> left, SFunction<X, ?> right) {
return leftJoin(LambdaUtils.getEntityClass(left), on -> on.eq(left, right));
return join(Constant.LEFT_JOIN, left, right);
}
/**
@ -42,7 +41,7 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
* @param function 条件
*/
default <T> Children leftJoin(Class<T> clazz, WrapperFunction<Entity> function) {
return join(Constant.LEFT_JOIN, clazz, function, null);
return join(Constant.LEFT_JOIN, clazz, function);
}
/**
@ -53,7 +52,7 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
* @param right 条件
*/
default <T, X> Children leftJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right, WrapperFunction<Entity> ext) {
return leftJoin(clazz, on -> on.eq(left, right), ext);
return join(Constant.LEFT_JOIN, clazz, left, right, ext);
}
/**
@ -63,7 +62,7 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
* @param right 条件
*/
default <T, X> Children leftJoin(SFunction<T, ?> left, SFunction<X, ?> right, WrapperFunction<Entity> ext) {
return leftJoin(LambdaUtils.getEntityClass(left), on -> on.eq(left, right), ext);
return join(Constant.LEFT_JOIN, left, right, ext);
}
/**
@ -72,94 +71,95 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
* leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...)
*
* @param clazz 关联实体类
* @param function 条件
* @param consumer 条件
*/
default <T> Children leftJoin(Class<T> clazz, WrapperFunction<Entity> function, WrapperFunction<Entity> ext) {
return join(Constant.LEFT_JOIN, clazz, function, ext);
default <T> Children leftJoin(Class<T> clazz, WrapperBiConsumer<Entity> consumer) {
return join(Constant.LEFT_JOIN, clazz, consumer);
}
/**
* ignore 参考 left join
*/
default <T, X> Children rightJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
return rightJoin(clazz, on -> on.eq(left, right));
return join(Constant.RIGHT_JOIN, clazz, left, right);
}
/**
* ignore 参考 left join
*/
default <T, X> Children rightJoin(SFunction<T, ?> left, SFunction<X, ?> right) {
return rightJoin(LambdaUtils.getEntityClass(left), on -> on.eq(left, right));
return join(Constant.RIGHT_JOIN, left, right);
}
/**
* ignore 参考 left join
*/
default <T> Children rightJoin(Class<T> clazz, WrapperFunction<Entity> function) {
return join(Constant.RIGHT_JOIN, clazz, function, null);
return join(Constant.RIGHT_JOIN, clazz, function);
}
/**
* ignore 参考 left join
*/
default <T, X> Children rightJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right, WrapperFunction<Entity> ext) {
return rightJoin(clazz, on -> on.eq(left, right), ext);
return join(Constant.RIGHT_JOIN, clazz, left, right, ext);
}
/**
* ignore 参考 left join
*/
default <T, X> Children rightJoin(SFunction<T, ?> left, SFunction<X, ?> right, WrapperFunction<Entity> ext) {
return rightJoin(LambdaUtils.getEntityClass(left), on -> on.eq(left, right), ext);
return join(Constant.RIGHT_JOIN, left, right, ext);
}
/**
* ignore 参考 left join
*/
default <T> Children rightJoin(Class<T> clazz, WrapperFunction<Entity> function, WrapperFunction<Entity> ext) {
return join(Constant.RIGHT_JOIN, clazz, function, ext);
default <T, X> Children rightJoin(Class<T> clazz, WrapperBiConsumer<Entity> consumer) {
return join(Constant.RIGHT_JOIN, clazz, consumer);
}
/**
* ignore 参考 left join
*/
default <T, X> Children innerJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
return innerJoin(clazz, on -> on.eq(left, right));
return join(Constant.INNER_JOIN, clazz, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default <T, X> Children innerJoin(SFunction<T, ?> left, SFunction<X, ?> right) {
return innerJoin(LambdaUtils.getEntityClass(left), on -> on.eq(left, right));
return join(Constant.INNER_JOIN, LambdaUtils.getEntityClass(left), on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default <T> Children innerJoin(Class<T> clazz, WrapperFunction<Entity> function) {
return join(Constant.INNER_JOIN, clazz, function, null);
return join(Constant.INNER_JOIN, clazz, function);
}
/**
* ignore 参考 left join
*/
default <T, X> Children innerJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right, WrapperFunction<Entity> ext) {
return innerJoin(clazz, on -> on.eq(left, right), ext);
return join(Constant.INNER_JOIN, clazz, left, right, ext);
}
/**
* ignore 参考 left join
*/
default <T, X> Children innerJoin(SFunction<T, ?> left, SFunction<X, ?> right, WrapperFunction<Entity> ext) {
return innerJoin(LambdaUtils.getEntityClass(left), on -> on.eq(left, right), ext);
return join(Constant.INNER_JOIN, left, right, ext);
}
/**
* ignore 参考 left join
*/
default <T> Children innerJoin(Class<T> clazz, WrapperFunction<Entity> function, WrapperFunction<Entity> ext) {
return join(Constant.INNER_JOIN, clazz, function, ext);
default <T> Children innerJoin(Class<T> clazz, WrapperBiConsumer<Entity> consumer) {
return join(Constant.INNER_JOIN, clazz, consumer);
}
@ -167,42 +167,42 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
* ignore 参考 left join
*/
default <T, X> Children fullJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right) {
return fullJoin(clazz, on -> on.eq(left, right));
return join(Constant.FULL_JOIN, clazz, left, right);
}
/**
* ignore 参考 left join
*/
default <T, X> Children fullJoin(SFunction<T, ?> left, SFunction<X, ?> right) {
return fullJoin(LambdaUtils.getEntityClass(left), on -> on.eq(left, right));
return join(Constant.FULL_JOIN, left, right);
}
/**
* ignore 参考 left join
*/
default <T> Children fullJoin(Class<T> clazz, WrapperFunction<Entity> function) {
return join(Constant.FULL_JOIN, clazz, function, null);
return join(Constant.FULL_JOIN, clazz, function);
}
/**
* ignore 参考 left join
*/
default <T, X> Children fullJoin(Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right, WrapperFunction<Entity> ext) {
return fullJoin(clazz, on -> on.eq(left, right), ext);
return join(Constant.FULL_JOIN, clazz, left, right, ext);
}
/**
* ignore 参考 left join
*/
default <T, X> Children fullJoin(SFunction<T, ?> left, SFunction<X, ?> right, WrapperFunction<Entity> ext) {
return fullJoin(LambdaUtils.getEntityClass(left), on -> on.eq(left, right), ext);
return join(Constant.FULL_JOIN, left, right, ext);
}
/**
* ignore 参考 left join
*/
default <T> Children fullJoin(Class<T> clazz, WrapperFunction<Entity> function, WrapperFunction<Entity> ext) {
return join(Constant.FULL_JOIN, clazz, function, ext);
default <T> Children fullJoin(Class<T> clazz, WrapperBiConsumer<Entity> consumer) {
return join(Constant.FULL_JOIN, clazz, consumer);
}
/**
@ -239,7 +239,7 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
* @param function 条件
*/
default <T> Children join(String keyWord, Class<T> clazz, WrapperFunction<Entity> function) {
return join(keyWord, clazz, function, null);
return join(keyWord, clazz, (on, e) -> function.apply(on));
}
/**
@ -250,7 +250,10 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
* @param right 条件
*/
default <T, X> Children join(String keyWord, Class<T> clazz, SFunction<T, ?> left, SFunction<X, ?> right, WrapperFunction<Entity> ext) {
return join(keyWord, clazz, on -> on.eq(left, right), ext);
return join(keyWord, clazz, (on, e) -> {
on.eq(left, right);
ext.apply(e);
});
}
/**
@ -260,11 +263,11 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
* @param right 条件
*/
default <T, X> Children join(String keyWord, SFunction<T, ?> left, SFunction<X, ?> right, WrapperFunction<Entity> ext) {
return join(keyWord, LambdaUtils.getEntityClass(left), on -> on.eq(left, right), ext);
return join(keyWord, LambdaUtils.getEntityClass(left), left, right, ext);
}
/**
* 内部使用, 不建议直接调用
*/
<T> Children join(String keyWord, Class<T> clazz, WrapperFunction<Entity> function, WrapperFunction<Entity> ext);
<T> Children join(String keyWord, Class<T> clazz, WrapperBiConsumer<Entity> consumer);
}

View File

@ -0,0 +1,9 @@
package com.github.yulichang.wrapper.interfaces;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
@FunctionalInterface
public interface WrapperBiConsumer<T> {
void accept(MPJLambdaWrapper<T> on, MPJLambdaWrapper<T> ext);
}

View File

@ -1,4 +1,4 @@
package com.github.yulichang.wrapper.interfaces.on;
package com.github.yulichang.wrapper.interfaces;
import com.github.yulichang.wrapper.MPJLambdaWrapper;

View File

@ -45,6 +45,17 @@ public class UserDO {
@TableLogic
private Boolean del;
private Integer createBy;
@TableField(exist = false)
private String createName;
private Integer updateBy;
@TableField(exist = false)
private String updateName;
@TableField(exist = false)
private String alias;

View File

@ -23,4 +23,5 @@ mybatis-plus:
# 打印 mybatis plus join banner
mybatis-plus-join:
banner: true
sub-table-logic: true
sub-table-logic: true
ms-cache: true

View File

@ -29,53 +29,53 @@ INSERT INTO area (id, province, city, area, postcode, del) VALUES (10022, '北
DELETE FROM `user`;
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES
( 1, 1, '张三 1', '{"id": 1,"name":"张三 1"}', 1, 1, 'https://url-01', '2022-01-01 12:00:00', false),
( 2, 1, '张三 2', '{"id": 2,"name":"张三 2"}', 1, 0, 'https://url-02', '2022-01-01 12:00:00', false),
( 3, 1, '张三 3', '{"id": 3,"name":"张三 3"}', 1, 0, 'https://url-03', '2022-01-01 12:00:00', false),
( 4, 1, '张三 4', '{"id": 4,"name":"张三 4"}', 1, 0, 'https://url-04', '2022-01-01 12:00:00', false),
( 5, 1, '张三 5', '{"id": 5,"name":"张三 5"}', 1, 0, 'https://url-05', '2022-01-01 12:00:00', false),
( 6, 1, '张三 6', '{"id": 6,"name":"张三 6"}', 1, 0, 'https://url-06', '2022-01-01 12:00:00', false),
( 7, 1, '张三 7', '{"id": 7,"name":"张三 7"}', 1, 0, 'https://url-07', '2022-01-01 12:00:00', false),
( 8, 1, '张三 8', '{"id": 8,"name":"张三 8"}', 1, 0, 'https://url-08', '2022-01-01 12:00:00', false),
( 9, 1, '张三 9', '{"id": 9,"name":"张三 9"}', 1, 0, 'https://url-09', '2022-01-01 12:00:00', false),
(10, 1, '张三10', '{"id":10,"name":"张三10"}', 1, 0, 'https://url-10', '2022-01-01 12:00:00', true ),
(11, 1, '张三11', '{"id":11,"name":"张三11"}', 1, 0, 'https://url-11', '2022-01-01 12:00:00', true ),
(12, 1, '张三12', '{"id":12,"name":"张三12"}', 1, 0, 'https://url-12', '2022-01-01 12:00:00', true ),
(13, 1, '张三13', '{"id":13,"name":"张三13"}', 1, 0, 'https://url-13', '2022-01-01 12:00:00', true ),
(14, 2, '张三14', '{"id":14,"name":"张三14"}', 1, 0, 'https://url-14', '2022-01-01 12:00:00', false),
(15, 2, '张三15', '{"id":15,"name":"张三15"}', 1, 0, 'https://url-15', '2022-01-01 12:00:00', false),
(16, 2, '张三16', '{"id":16,"name":"张三16"}', 1, 0, 'https://url-16', '2022-01-01 12:00:00', false),
(17, 2, '张三17', '{"id":17,"name":"张三17"}', 1, 0, 'https://url-17', '2022-01-01 12:00:00', false),
(18, 2, '张三18', '{"id":18,"name":"张三18"}', 1, 0, 'https://url-18', '2022-01-01 12:00:00', false),
(19, 2, '张三19', '{"id":19,"name":"张三19"}', 1, 0, 'https://url-19', '2022-01-01 12:00:00', true ),
(20, 2, '张三20', '{"id":20,"name":"张三20"}', 1, 0, 'https://url-20', '2022-01-01 12:00:00', true ),
(21, 2, '张三21', '{"id":21,"name":"张三21"}', 1, 0, 'https://url-21', '2022-01-01 12:00:00', true ),
(22, 2, '张三22', '{"id":22,"name":"张三22"}', 1, 0, 'https://url-22', '2022-01-01 12:00:00', true );
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, create_by, update_by, del) VALUES
( 1, 1, '张三 1', '{"id": 1,"name":"张三 1"}', 1, 1, 'https://url-01', '2022-01-01 12:00:00', 1, 2, false),
( 2, 1, '张三 2', '{"id": 2,"name":"张三 2"}', 1, 0, 'https://url-02', '2022-01-01 12:00:00', 2, 3, false),
( 3, 1, '张三 3', '{"id": 3,"name":"张三 3"}', 1, 0, 'https://url-03', '2022-01-01 12:00:00', 3, 2, false),
( 4, 1, '张三 4', '{"id": 4,"name":"张三 4"}', 1, 0, 'https://url-04', '2022-01-01 12:00:00', 9, 2, false),
( 5, 1, '张三 5', '{"id": 5,"name":"张三 5"}', 1, 0, 'https://url-05', '2022-01-01 12:00:00', 1, 2, false),
( 6, 1, '张三 6', '{"id": 6,"name":"张三 6"}', 1, 0, 'https://url-06', '2022-01-01 12:00:00', 1, 2, false),
( 7, 1, '张三 7', '{"id": 7,"name":"张三 7"}', 1, 0, 'https://url-07', '2022-01-01 12:00:00', 1, 2, false),
( 8, 1, '张三 8', '{"id": 8,"name":"张三 8"}', 1, 0, 'https://url-08', '2022-01-01 12:00:00', 1, 2, false),
( 9, 1, '张三 9', '{"id": 9,"name":"张三 9"}', 1, 0, 'https://url-09', '2022-01-01 12:00:00', 1, 2, false),
(10, 1, '张三10', '{"id":10,"name":"张三10"}', 1, 0, 'https://url-10', '2022-01-01 12:00:00', 1, 2, true ),
(11, 1, '张三11', '{"id":11,"name":"张三11"}', 1, 0, 'https://url-11', '2022-01-01 12:00:00', 1, 2, true ),
(12, 1, '张三12', '{"id":12,"name":"张三12"}', 1, 0, 'https://url-12', '2022-01-01 12:00:00', 1, 2, true ),
(13, 1, '张三13', '{"id":13,"name":"张三13"}', 1, 0, 'https://url-13', '2022-01-01 12:00:00', 1, 2, true ),
(14, 2, '张三14', '{"id":14,"name":"张三14"}', 1, 0, 'https://url-14', '2022-01-01 12:00:00', 1, 2, false),
(15, 2, '张三15', '{"id":15,"name":"张三15"}', 1, 0, 'https://url-15', '2022-01-01 12:00:00', 1, 2, false),
(16, 2, '张三16', '{"id":16,"name":"张三16"}', 1, 0, 'https://url-16', '2022-01-01 12:00:00', 1, 2, false),
(17, 2, '张三17', '{"id":17,"name":"张三17"}', 1, 0, 'https://url-17', '2022-01-01 12:00:00', 1, 2, false),
(18, 2, '张三18', '{"id":18,"name":"张三18"}', 1, 0, 'https://url-18', '2022-01-01 12:00:00', 1, 2, false),
(19, 2, '张三19', '{"id":19,"name":"张三19"}', 1, 0, 'https://url-19', '2022-01-01 12:00:00', 1, 2, true ),
(20, 2, '张三20', '{"id":20,"name":"张三20"}', 1, 0, 'https://url-20', '2022-01-01 12:00:00', 1, 2, true ),
(21, 2, '张三21', '{"id":21,"name":"张三21"}', 1, 0, 'https://url-21', '2022-01-01 12:00:00', 1, 2, true ),
(22, 2, '张三22', '{"id":22,"name":"张三22"}', 1, 0, 'https://url-22', '2022-01-01 12:00:00', 1, 2, true );
DELETE FROM address;
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 1, 1, 10001, '10000000001', '曹县01', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 2, 1, 10002, '10000000002', '曹县02', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 3, 1, 10003, '10000000003', '曹县03', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 4, 1, 10004, '10000000004', '曹县04', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 5, 1, 10005, '10000000005', '曹县05', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 6, 1, 10006, '10000000006', '曹县06', true );
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 7, 1, 10007, '10000000007', '曹县07', true );
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 8, 1, 10008, '10000000008', '曹县08', true );
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 9, 1, 10009, '10000000009', '曹县09', true );
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (10,10, 10010, '10000000010', '曹县10', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (11,11, 10011, '10000000011', '曹县11', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (12,12, 10012, '10000000012', '曹县12', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (13,13, 10013, '10000000013', '曹县13', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (14,14, 10014, '10000000014', '曹县14', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (15,15, 10015, '10000000015', '曹县15', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (16,16, 10016, '10000000016', '曹县16', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (17,17, 10017, '10000000017', '曹县17', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (18,18, 10018, '10000000018', '曹县18', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (19,19, 10019, '10000000019', '曹县19', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (20,20, 10020, '10000000020', '曹县20', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (21,21, 10021, '10000000021', '曹县21', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (22,22, 10022, '10000000022', '曹县22', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 1, 1, 10001, '10000000001', '朝阳01', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 2, 1, 10002, '10000000002', '朝阳02', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 3, 1, 10003, '10000000003', '朝阳03', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 4, 1, 10004, '10000000004', '朝阳04', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 5, 1, 10005, '10000000005', '朝阳05', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 6, 1, 10006, '10000000006', '朝阳06', true );
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 7, 1, 10007, '10000000007', '朝阳07', true );
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 8, 1, 10008, '10000000008', '朝阳08', true );
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 9, 1, 10009, '10000000009', '朝阳09', true );
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (10,10, 10010, '10000000010', '朝阳10', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (11,11, 10011, '10000000011', '朝阳11', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (12,12, 10012, '10000000012', '朝阳12', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (13,13, 10013, '10000000013', '朝阳13', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (14,14, 10014, '10000000014', '朝阳14', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (15,15, 10015, '10000000015', '朝阳15', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (16,16, 10016, '10000000016', '朝阳16', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (17,17, 10017, '10000000017', '朝阳17', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (18,18, 10018, '10000000018', '朝阳18', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (19,19, 10019, '10000000019', '朝阳19', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (20,20, 10020, '10000000020', '朝阳20', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (21,21, 10021, '10000000021', '朝阳21', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (22,22, 10022, '10000000022', '朝阳22', false);

View File

@ -28,6 +28,8 @@ create table `user`
sex tinyint not null,
head_img varchar(255) not null,
create_time datetime not null,
create_by int not null,
update_by int not null,
del bit
);

View File

@ -113,14 +113,30 @@ class LambdaWrapperTest {
*/
@Test
void testInner() {
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
// //自连接
// MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
// .disableSubLogicDel()//关闭副表逻辑删除
.disableLogicDel()//关闭主表逻辑删除
//// .disableLogicDel()//关闭主表逻辑删除
// .selectAll(UserDO.class)
// .selectCollection(UserDO.class, UserDO::getChildren)
// .leftJoin(UserDO.class, UserDO::getPid, UserDO::getId);
// List<UserDO> list = userMapper.selectJoinList(UserDO.class, wrapper);
//// assert list.size() == 2 && list.get(0).getChildren().size() == 9;
// System.out.println(list);
//关联一张表多次
MPJLambdaWrapper<UserDO> w = new MPJLambdaWrapper<UserDO>()
.disableLogicDel()
.disableSubLogicDel()
.selectAll(UserDO.class)
.selectCollection(UserDO.class, UserDO::getChildren)
.leftJoin(UserDO.class, UserDO::getPid, UserDO::getId);
List<UserDO> list = userMapper.selectJoinList(UserDO.class, wrapper);
System.out.println(list);
.leftJoin(UserDO.class, UserDO::getId, UserDO::getCreateBy, ext -> ext.selectAs(UserDO::getName, UserDO::getCreateName))
.leftJoin(UserDO.class, (on, ext) -> {
on.eq(UserDO::getId, UserDO::getUpdateBy);
ext.selectAs(UserDO::getName, UserDO::getUpdateName);
})
.eq(UserDO::getId, UserDO::getId);
List<UserDO> dos = userMapper.selectJoinList(UserDO.class, w);
assert dos.get(0).getCreateName() != null && dos.get(0).getUpdateName() != null;
MPJLambdaWrapper<UserDO> wrapper1 = new MPJLambdaWrapper<UserDO>()
.disableSubLogicDel()
@ -134,6 +150,7 @@ class LambdaWrapperTest {
.le(UserDO::getId, 4);
List<UserDO> list1 = userMapper.selectJoinList(UserDO.class, wrapper1);
System.out.println(wrapper1.getSqlSegment());
System.out.println(wrapper1.getSqlSelect());
assert "(t1.id <= #{ew.paramNameValuePairs.MPGENVAL1} AND t.id <= #{ew.paramNameValuePairs.MPGENVAL2})".equals(wrapper1.getSqlSegment());
System.out.println(list1);
}
@ -267,7 +284,7 @@ class LambdaWrapperTest {
}
/**
* 关联查询返回map
* 原生查询
*/
@Test
void testMP() {
@ -276,4 +293,16 @@ class LambdaWrapperTest {
.lt(UserDO::getId, 8));
assert dos.size() == 4;
}
/**
* 函数测试
*/
@Test
void testFunc() {
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.selectAll(UserDO.class);
List<UserDO> dos = userMapper.selectJoinList(UserDO.class, wrapper);
System.out.println(1);
}
}

View File

@ -33,6 +33,7 @@
<module>mybatis-plus-join-boot-starter</module>
<module>mybatis-plus-join-core</module>
<module>mybatis-plus-join-annotation</module>
<module>mybatis-plus-join-test</module>
</modules>
<properties>