mirror of
https://gitee.com/best_handsome/mybatis-plus-join
synced 2025-07-11 00:02:22 +08:00
自连接和关联同一张表N次
This commit is contained in:
parent
d4a0843225
commit
ad1360e3c6
@ -186,7 +186,7 @@ public class MPJInterceptor implements Interceptor {
|
||||
}
|
||||
} else {
|
||||
Field field = fieldMap.get(i.getColumProperty());
|
||||
columnSet.add(i.getColumProperty());
|
||||
columnSet.add(i.getTagColumn());
|
||||
if (Objects.nonNull(field)) {
|
||||
ResultMapping.Builder builder = new ResultMapping.Builder(ms.getConfiguration(), i.getColumProperty(),
|
||||
i.getTagColumn(), field.getType());
|
||||
|
@ -5,11 +5,11 @@ 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 com.github.yulichang.wrapper.segments.Select;
|
||||
import com.github.yulichang.wrapper.segments.SelectCache;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
@ -28,27 +28,22 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
|
||||
* 关联的表
|
||||
*/
|
||||
protected TableList tableList = new TableList();
|
||||
/**
|
||||
* 表别名
|
||||
*/
|
||||
@Getter
|
||||
protected String index;
|
||||
|
||||
|
||||
@Override
|
||||
protected <X> String columnToString(X column, boolean isJoin) {
|
||||
return columnToString((SFunction<?, ?>) column, isJoin);
|
||||
protected <X> String columnToString(String index, X column, boolean isJoin) {
|
||||
return columnToString(index, (SFunction<?, ?>) column, isJoin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SafeVarargs
|
||||
protected final <X> String columnsToString(boolean isJoin, X... columns) {
|
||||
return Arrays.stream(columns).map(i -> columnToString((SFunction<?, ?>) i, isJoin)).collect(joining(StringPool.COMMA));
|
||||
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 String columnToString(SFunction<?, ?> column, boolean isJoin) {
|
||||
protected String columnToString(String index, SFunction<?, ?> column, boolean isJoin) {
|
||||
Class<?> entityClass = LambdaUtils.getEntityClass(column);
|
||||
return Constant.TABLE_ALIAS + getDefault(entityClass, isJoin) + StringPool.DOT +
|
||||
return Constant.TABLE_ALIAS + getDefault(index, entityClass, isJoin) + StringPool.DOT +
|
||||
getCache(column).getTagColumn();
|
||||
}
|
||||
|
||||
@ -58,26 +53,42 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
|
||||
return cacheMap.get(LambdaUtils.getName(fn));
|
||||
}
|
||||
|
||||
protected String getDefault(Class<?> clazz, boolean isJoin) {
|
||||
protected String getDefault(String index, Class<?> clazz, boolean isJoin) {
|
||||
if (Objects.isNull(index)) {
|
||||
if (Objects.equals(clazz, getEntityClass())) {
|
||||
return StringPool.EMPTY;
|
||||
}
|
||||
//正序
|
||||
Table table = tableList.getPositive(clazz);
|
||||
return Objects.isNull(table.index) ? StringPool.EMPTY : table.index;
|
||||
}
|
||||
Table table = tableList.get(clazz, index);
|
||||
if (Objects.nonNull(table.getIndex())) {
|
||||
if (getEntityClass() == null) {
|
||||
return table.getIndex();
|
||||
}
|
||||
if (isJoin && joinClass == getEntityClass()) {
|
||||
return StringPool.EMPTY;
|
||||
if (isJoin) {
|
||||
//除自己以外的倒序第一个
|
||||
Table t = tableList.getOrElse(clazz, index);
|
||||
if (Objects.isNull(t.getIndex())) {
|
||||
return StringPool.EMPTY;
|
||||
}
|
||||
return t.getIndex();
|
||||
}
|
||||
return table.getIndex();
|
||||
}
|
||||
return StringPool.EMPTY;
|
||||
}
|
||||
|
||||
protected String getDefaultSelect(Class<?> clazz, boolean myself) {
|
||||
protected String getDefaultSelect(String index, Class<?> clazz, Select s) {
|
||||
if (s.isLabel()) {
|
||||
if (Objects.nonNull(s.getIndex())) {
|
||||
return s.getIndex();
|
||||
} else {
|
||||
Table table = tableList.get(s.getClazz());
|
||||
return Objects.isNull(table.index) ? StringPool.EMPTY : table.index;
|
||||
}
|
||||
}
|
||||
//外层select
|
||||
Table table = tableList.get(clazz, index);
|
||||
if (Objects.nonNull(table.getIndex())) {
|
||||
if (myself) {
|
||||
return StringPool.EMPTY;
|
||||
}
|
||||
return table.getIndex();
|
||||
}
|
||||
return StringPool.EMPTY;
|
||||
@ -85,7 +96,7 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
|
||||
|
||||
public static class TableList {
|
||||
|
||||
private static final Table DEFAULT_TABLE = new Table(null, null);
|
||||
private static final Table DEFAULT_TABLE = new Table(null, StringPool.EMPTY);
|
||||
|
||||
private final List<Table> list = new ArrayList<>();
|
||||
|
||||
@ -93,8 +104,12 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
|
||||
this.list.add(new Table(clazz, index));
|
||||
}
|
||||
|
||||
private Table get(Class<?> clazz) {
|
||||
for (Table t : list) {
|
||||
public Table get(Class<?> clazz) {
|
||||
if (list.isEmpty()) {
|
||||
return DEFAULT_TABLE;
|
||||
}
|
||||
for (int i = list.size() - 1; i >= 0; i--) {
|
||||
Table t = list.get(i);
|
||||
if (clazz == t.clazz) {
|
||||
return t;
|
||||
}
|
||||
@ -102,15 +117,49 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
|
||||
return DEFAULT_TABLE;
|
||||
}
|
||||
|
||||
|
||||
public Table get(Class<?> clazz, String index) {
|
||||
if (Objects.isNull(index)) {
|
||||
return get(clazz);
|
||||
}
|
||||
if (list.isEmpty()) {
|
||||
return DEFAULT_TABLE;
|
||||
}
|
||||
//倒序
|
||||
for (int i = list.size() - 1; i >= 0; i--) {
|
||||
Table t = list.get(i);
|
||||
if (clazz == t.clazz && Objects.equals(index, t.getIndex())) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return get(clazz);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public Table getPositive(Class<?> clazz, String index) {
|
||||
if (Objects.isNull(index)) {
|
||||
return get(clazz);
|
||||
}
|
||||
if (list.isEmpty()) {
|
||||
return DEFAULT_TABLE;
|
||||
}
|
||||
for (Table t : list) {
|
||||
if (clazz == t.clazz && Objects.equals(index, t.getIndex())) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return getPositive(clazz);
|
||||
}
|
||||
|
||||
public Table getPositive(Class<?> clazz) {
|
||||
if (list.isEmpty()) {
|
||||
return DEFAULT_TABLE;
|
||||
}
|
||||
for (Table t : list) {
|
||||
if (clazz == t.clazz) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return DEFAULT_TABLE;
|
||||
}
|
||||
|
||||
@ -125,14 +174,33 @@ public abstract class MPJAbstractLambdaWrapper<T, Children extends MPJAbstractLa
|
||||
public boolean isEmpty() {
|
||||
return list.isEmpty();
|
||||
}
|
||||
|
||||
public Table getOrElse(Class<?> clazz, String index) {
|
||||
if (Objects.isNull(index)) {
|
||||
return get(clazz);
|
||||
}
|
||||
//倒序
|
||||
for (int i = list.size() - 1; i >= 0; i--) {
|
||||
Table t = list.get(i);
|
||||
if (clazz == t.clazz) {
|
||||
if (Objects.equals(index, t.getIndex())) {
|
||||
continue;
|
||||
}
|
||||
if (Integer.parseInt(t.getIndex()) < Integer.parseInt(index)) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
return DEFAULT_TABLE;
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
@AllArgsConstructor
|
||||
public static class Table {
|
||||
private Class<?> clazz;
|
||||
private final Class<?> clazz;
|
||||
|
||||
private String index;
|
||||
private final String index;
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,11 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
||||
* 占位符
|
||||
*/
|
||||
protected final Children typedThis = (Children) this;
|
||||
/**
|
||||
* 表别名
|
||||
*/
|
||||
@Getter
|
||||
protected String index;
|
||||
/**
|
||||
* 必要度量
|
||||
*/
|
||||
@ -191,13 +196,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, false), BETWEEN,
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, 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, false), NOT_BETWEEN,
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), NOT_BETWEEN,
|
||||
() -> formatParam(null, val1), AND, () -> formatParam(null, val2)));
|
||||
}
|
||||
|
||||
@ -269,43 +274,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, false), IS_NULL));
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IS_NULL));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> Children isNotNull(boolean condition, SFunction<X, ?> column) {
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), IS_NOT_NULL));
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IS_NOT_NULL));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> Children in(boolean condition, SFunction<X, ?> column, Collection<?> coll) {
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), IN, inExpression(coll)));
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IN, inExpression(coll)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> Children in(boolean condition, SFunction<X, ?> column, Object... values) {
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), IN, inExpression(values)));
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IN, inExpression(values)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> Children notIn(boolean condition, SFunction<X, ?> column, Collection<?> coll) {
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), NOT_IN, inExpression(coll)));
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), NOT_IN, inExpression(coll)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> Children notIn(boolean condition, SFunction<X, ?> column, Object... values) {
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), NOT_IN, inExpression(values)));
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), NOT_IN, inExpression(values)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> Children inSql(boolean condition, SFunction<X, ?> column, String inValue) {
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, false), IN,
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, 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, false), NOT_IN,
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), NOT_IN,
|
||||
() -> String.format("(%s)", inValue)));
|
||||
}
|
||||
|
||||
@ -313,7 +318,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(false, columns));
|
||||
String one = (StringPool.COMMA + columnsToString(index, false, columns));
|
||||
final String finalOne = one;
|
||||
appendSqlSegments(GROUP_BY, () -> finalOne);
|
||||
}
|
||||
@ -323,9 +328,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, false);
|
||||
String one = columnToString(index, column, false);
|
||||
if (ArrayUtils.isNotEmpty(columns)) {
|
||||
one += (StringPool.COMMA + columnsToString(false, columns));
|
||||
one += (StringPool.COMMA + columnsToString(index, false, columns));
|
||||
}
|
||||
final String finalOne = one;
|
||||
appendSqlSegments(GROUP_BY, () -> finalOne);
|
||||
@ -338,7 +343,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), false), mode));
|
||||
columnToSqlSegment(index, columnSqlInjectFilter(c), false), mode));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -349,7 +354,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), false), mode));
|
||||
columnToSqlSegment(index, columnSqlInjectFilter(c), false), mode));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -358,10 +363,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, false), mode);
|
||||
appendSqlSegments(ORDER_BY, columnToSqlSegment(index, column, false), mode);
|
||||
if (ArrayUtils.isNotEmpty(columns)) {
|
||||
Arrays.stream(columns).forEach(c -> appendSqlSegments(ORDER_BY,
|
||||
columnToSqlSegment(columnSqlInjectFilter(c), false), mode));
|
||||
columnToSqlSegment(index, columnSqlInjectFilter(c), false), mode));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -408,7 +413,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, false), keyword,
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), keyword,
|
||||
() -> formatParam(null, SqlUtils.concatLike(val, sqlLike))));
|
||||
}
|
||||
|
||||
@ -421,13 +426,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, true), sqlKeyword,
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), 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, false), sqlKeyword,
|
||||
columnToSqlSegment(val, true)));
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), sqlKeyword,
|
||||
columnToSqlSegment(index, val, true)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -609,14 +614,14 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
||||
/**
|
||||
* 获取 columnName
|
||||
*/
|
||||
protected final <X> ISqlSegment columnToSqlSegment(SFunction<X, ?> column, boolean isJoin) {
|
||||
return () -> columnToString(column, isJoin);
|
||||
protected final <X> ISqlSegment columnToSqlSegment(String index, SFunction<X, ?> column, boolean isJoin) {
|
||||
return () -> columnToString(index, column, isJoin);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 columnName
|
||||
*/
|
||||
protected <X> String columnToString(X column, boolean isJoin) {
|
||||
protected <X> String columnToString(String index, X column, boolean isJoin) {
|
||||
return (String) column;
|
||||
}
|
||||
|
||||
@ -625,8 +630,8 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
|
||||
*
|
||||
* @param columns 多字段
|
||||
*/
|
||||
protected <X> String columnsToString(boolean isJoin, X... columns) {
|
||||
return Arrays.stream(columns).map(i -> this.columnToString(i, isJoin)).collect(joining(StringPool.COMMA));
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -675,36 +680,4 @@ 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, S, U> Children between(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val1, SFunction<U, ?> 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, 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, 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, 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, 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, false), NOT_BETWEEN,
|
||||
columnToSqlSegment(val1, true), AND, () -> formatParam(null, val2)));
|
||||
}
|
||||
}
|
||||
|
@ -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.OnFunction;
|
||||
import com.github.yulichang.wrapper.interfaces.on.WrapperFunction;
|
||||
import com.github.yulichang.wrapper.resultmap.MybatisLabel;
|
||||
import com.github.yulichang.wrapper.segments.Select;
|
||||
import com.github.yulichang.wrapper.segments.SelectCache;
|
||||
@ -27,6 +27,7 @@ import lombok.Getter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -104,7 +105,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 keyWord, Class<?> joinClass) {
|
||||
TableList tableList, String index, String keyWord, Class<?> joinClass) {
|
||||
super.setEntity(entity);
|
||||
super.setEntityClass(entityClass);
|
||||
this.paramNameSeq = paramNameSeq;
|
||||
@ -115,6 +116,7 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
||||
this.sqlComment = sqlComment;
|
||||
this.sqlFirst = sqlFirst;
|
||||
this.tableList = tableList;
|
||||
this.index = index;
|
||||
this.keyWord = keyWord;
|
||||
this.joinClass = joinClass;
|
||||
}
|
||||
@ -173,7 +175,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 + getDefaultSelect(i.getClazz(), (i.getClazz() == getEntityClass() && !i.isLabel())) + StringPool.DOT + i.getColumn();
|
||||
String str = Constant.TABLE_ALIAS + getDefaultSelect(i.getIndex(), i.getClazz(), i) + StringPool.DOT + i.getColumn();
|
||||
return i.isFunc() ? (String.format(i.getFunc().getSql(), str) + Constant.AS + i.getAlias()) : (i.isHasAlias() ? (str + Constant.AS + i.getAlias()) : str);
|
||||
}).collect(Collectors.joining(StringPool.COMMA));
|
||||
sqlSelect.setStringValue(s);
|
||||
@ -216,13 +218,13 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
||||
*/
|
||||
@Override
|
||||
protected MPJLambdaWrapper<T> instance() {
|
||||
return instance(null, null);
|
||||
return instance(index, null, null);
|
||||
}
|
||||
|
||||
protected MPJLambdaWrapper<T> instance(String keyWord, Class<?> joinClass) {
|
||||
protected MPJLambdaWrapper<T> instance(String index, String keyWord, Class<?> joinClass) {
|
||||
return new MPJLambdaWrapper<>(getEntity(), getEntityClass(), null, paramNameSeq, paramNameValuePairs,
|
||||
new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
|
||||
this.tableList, keyWord, joinClass);
|
||||
this.tableList, index, keyWord, joinClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -285,12 +287,21 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
||||
return this.logicSql;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用此方法 keyword 前后需要带空格 比如 " LEFT JOIN " " RIGHT JOIN "
|
||||
*/
|
||||
@Override
|
||||
public <R> MPJLambdaWrapper<T> join(String keyWord, Class<R> clazz, OnFunction<T> function) {
|
||||
MPJLambdaWrapper<T> apply = function.apply(instance(keyWord, clazz));
|
||||
tableList.add(clazz, String.valueOf(tableIndex));
|
||||
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);
|
||||
tableIndex++;
|
||||
if (Objects.nonNull(ext)) {
|
||||
this.index = name;
|
||||
MPJLambdaWrapper<T> wrapper = ext.apply(typedThis);
|
||||
wrapper.index = null;
|
||||
}
|
||||
return typedThis;
|
||||
}
|
||||
}
|
||||
|
@ -91,10 +91,26 @@ public interface Query<Children> extends Serializable {
|
||||
default <S> Children selectAs(SFunction<S, ?> column, String alias) {
|
||||
Class<?> aClass = LambdaUtils.getEntityClass(column);
|
||||
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(aClass);
|
||||
String index = getIndex();
|
||||
getSelectColum().add(new SelectAlias(cacheMap.get(LambdaUtils.getName(column)), getIndex(), alias));
|
||||
return getChildren();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询实体类全部字段
|
||||
*/
|
||||
default Children selectAll(Class<?> clazz) {
|
||||
getSelectColum().addAll(ColumnCache.getListField(clazz).stream().map(i ->
|
||||
new SelectNormal(i, getIndex())).collect(Collectors.toList()));
|
||||
return getChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
* select sql 片段
|
||||
*/
|
||||
String getSqlSelect();
|
||||
|
||||
/**
|
||||
* 聚合函数查询
|
||||
* <p>
|
||||
@ -131,19 +147,6 @@ public interface Query<Children> extends Serializable {
|
||||
return selectFunc(funcEnum, column, LambdaUtils.getName(alias));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询实体类全部字段
|
||||
*/
|
||||
default Children selectAll(Class<?> clazz) {
|
||||
getSelectColum().addAll(ColumnCache.getListField(clazz).stream().map(i ->
|
||||
new SelectNormal(i, getIndex())).collect(Collectors.toList()));
|
||||
return getChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
* select sql 片段
|
||||
*/
|
||||
String getSqlSelect();
|
||||
|
||||
/* 默认聚合函数扩展 */
|
||||
|
||||
|
@ -4,7 +4,7 @@ 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.OnFunction;
|
||||
import com.github.yulichang.wrapper.interfaces.on.WrapperFunction;
|
||||
|
||||
/**
|
||||
* @author yulichang
|
||||
@ -41,8 +41,41 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
|
||||
* @param clazz 关联实体类
|
||||
* @param function 条件
|
||||
*/
|
||||
default <T> Children leftJoin(Class<T> clazz, OnFunction<Entity> function) {
|
||||
return join(Constant.LEFT_JOIN, clazz, function);
|
||||
default <T> Children leftJoin(Class<T> clazz, WrapperFunction<Entity> function) {
|
||||
return join(Constant.LEFT_JOIN, clazz, function, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* left join
|
||||
*
|
||||
* @param clazz 关联的实体类
|
||||
* @param left 条件
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* left join
|
||||
*
|
||||
* @param left 条件
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, WrapperFunction<Entity> function, WrapperFunction<Entity> ext) {
|
||||
return join(Constant.LEFT_JOIN, clazz, function, ext);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,8 +95,29 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T> Children rightJoin(Class<T> clazz, OnFunction<Entity> function) {
|
||||
return join(Constant.RIGHT_JOIN, clazz, function);
|
||||
default <T> Children rightJoin(Class<T> clazz, WrapperFunction<Entity> function) {
|
||||
return join(Constant.RIGHT_JOIN, clazz, function, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T> Children rightJoin(Class<T> clazz, WrapperFunction<Entity> function, WrapperFunction<Entity> ext) {
|
||||
return join(Constant.RIGHT_JOIN, clazz, function, ext);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,8 +137,29 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T> Children innerJoin(Class<T> clazz, OnFunction<Entity> function) {
|
||||
return join(Constant.INNER_JOIN, clazz, function);
|
||||
default <T> Children innerJoin(Class<T> clazz, WrapperFunction<Entity> function) {
|
||||
return join(Constant.INNER_JOIN, clazz, function, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T> Children innerJoin(Class<T> clazz, WrapperFunction<Entity> function, WrapperFunction<Entity> ext) {
|
||||
return join(Constant.INNER_JOIN, clazz, function, ext);
|
||||
}
|
||||
|
||||
|
||||
@ -105,16 +180,41 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity> {
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T> Children fullJoin(Class<T> clazz, OnFunction<Entity> function) {
|
||||
return join(Constant.FULL_JOIN, clazz, function);
|
||||
default <T> Children fullJoin(Class<T> clazz, WrapperFunction<Entity> function) {
|
||||
return join(Constant.FULL_JOIN, clazz, function, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore 参考 left join
|
||||
*/
|
||||
default <T> Children fullJoin(Class<T> clazz, WrapperFunction<Entity> function, WrapperFunction<Entity> ext) {
|
||||
return join(Constant.FULL_JOIN, clazz, function, ext);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 调用此方法 keyword 前后需要带空格 比如 " LEFT JOIN " " RIGHT JOIN "
|
||||
* <p>
|
||||
* 查询基类 可以直接调用此方法实现以上所有功能
|
||||
*
|
||||
* @param keyWord 连表关键字
|
||||
* @param clazz 连表实体类
|
||||
* @param function 关联条件
|
||||
* @param ext 扩展 用于关联表的 select 和 where
|
||||
*/
|
||||
<T> Children join(String keyWord, Class<T> clazz, OnFunction<Entity> function);
|
||||
<T> Children join(String keyWord, Class<T> clazz, WrapperFunction<Entity> function, WrapperFunction<Entity> ext);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import com.github.yulichang.wrapper.resultmap.MybatisLabel;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@SuppressWarnings({"unchecked", "unused"})
|
||||
public interface QueryLabel<Children> {
|
||||
@ -42,18 +43,23 @@ public interface QueryLabel<Children> {
|
||||
* @param <F> 包装类集合字段泛型
|
||||
*/
|
||||
default <S, C, Z, F extends java.util.Collection<?>> Children selectCollection(Class<C> child, SFunction<S, F> dtoField) {
|
||||
return selectCollection(null, child, dtoField);
|
||||
}
|
||||
|
||||
default <S, C, Z, F extends java.util.Collection<?>> Children selectCollection(Integer index, Class<C> child, SFunction<S, F> dtoField) {
|
||||
String dtoFieldName = LambdaUtils.getName(dtoField);
|
||||
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
|
||||
Map<String, Field> fieldMap = MPJReflectionKit.getFieldMap(dtoClass);
|
||||
Field field = fieldMap.get(dtoFieldName);
|
||||
Class<?> genericType = MPJReflectionKit.getGenericType(field);
|
||||
MybatisLabel.Builder<C, Z> builder;
|
||||
String s = Objects.isNull(index) ? null : index.toString();
|
||||
if (genericType == null || genericType.isAssignableFrom(child)) {
|
||||
//找不到集合泛型 List List<?> List<Object> , 直接查询数据库实体
|
||||
builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType());
|
||||
builder = new MybatisLabel.Builder<>(s, dtoFieldName, child, field.getType());
|
||||
} else {
|
||||
Class<Z> ofType = (Class<Z>) genericType;
|
||||
builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), ofType, true);
|
||||
builder = new MybatisLabel.Builder<>(s, dtoFieldName, child, field.getType(), ofType, true);
|
||||
}
|
||||
addLabel(builder.build());
|
||||
return getChildren();
|
||||
@ -90,13 +96,21 @@ public interface QueryLabel<Children> {
|
||||
default <S, C, Z, F extends java.util.Collection<Z>> Children selectCollection(Class<C> child,
|
||||
SFunction<S, F> dtoField,
|
||||
MFunc<MybatisLabel.Builder<C, Z>> collection) {
|
||||
return selectCollection(null, child, dtoField, collection);
|
||||
}
|
||||
|
||||
default <S, C, Z, F extends java.util.Collection<Z>> Children selectCollection(Integer index,
|
||||
Class<C> child,
|
||||
SFunction<S, F> dtoField,
|
||||
MFunc<MybatisLabel.Builder<C, Z>> collection) {
|
||||
String dtoFieldName = LambdaUtils.getName(dtoField);
|
||||
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
|
||||
Field field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
|
||||
//获取集合泛型
|
||||
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);
|
||||
MybatisLabel.Builder<C, Z> builder = new MybatisLabel.Builder<>(Objects.isNull(index) ? null : index.toString(),
|
||||
dtoFieldName, child, field.getType(), ofType, false);
|
||||
MybatisLabel.Builder<C, Z> czBuilder = collection.apply(builder);
|
||||
addLabel(czBuilder.build());
|
||||
return getChildren();
|
||||
@ -108,13 +122,18 @@ public interface QueryLabel<Children> {
|
||||
* @since 1.3.0
|
||||
*/
|
||||
default <S, C, F> Children selectAssociation(Class<C> child, SFunction<S, F> dtoField) {
|
||||
return selectAssociation(null, child, dtoField);
|
||||
}
|
||||
|
||||
default <S, C, F> Children selectAssociation(Integer index, Class<C> child, SFunction<S, F> dtoField) {
|
||||
String dtoFieldName = LambdaUtils.getName(dtoField);
|
||||
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
|
||||
Map<String, Field> fieldMap = MPJReflectionKit.getFieldMap(dtoClass);
|
||||
Field field = fieldMap.get(dtoFieldName);
|
||||
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
|
||||
MybatisLabel.Builder<C, F> builder;
|
||||
builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), (Class<F>) field.getType(), true);
|
||||
builder = new MybatisLabel.Builder<>(Objects.isNull(index) ? null : index.toString(),
|
||||
dtoFieldName, child, field.getType(), (Class<F>) field.getType(), true);
|
||||
addLabel(builder.build());
|
||||
return getChildren();
|
||||
}
|
||||
@ -126,11 +145,17 @@ public interface QueryLabel<Children> {
|
||||
*/
|
||||
default <S, C, F> Children selectAssociation(Class<C> child, SFunction<S, F> dtoField,
|
||||
MFunc<MybatisLabel.Builder<C, F>> collection) {
|
||||
return selectAssociation(null, child, dtoField, collection);
|
||||
}
|
||||
|
||||
default <S, C, F> Children selectAssociation(Integer index, Class<C> child, SFunction<S, F> dtoField,
|
||||
MFunc<MybatisLabel.Builder<C, F>> collection) {
|
||||
String dtoFieldName = LambdaUtils.getName(dtoField);
|
||||
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
|
||||
Field field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
|
||||
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
|
||||
MybatisLabel.Builder<C, F> builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), (Class<F>) child, false);
|
||||
MybatisLabel.Builder<C, F> builder = new MybatisLabel.Builder<>(Objects.isNull(index) ? null : index.toString(),
|
||||
dtoFieldName, child, field.getType(), (Class<F>) child, false);
|
||||
MybatisLabel.Builder<C, F> cfBuilder = collection.apply(builder);
|
||||
addLabel(cfBuilder.build());
|
||||
return getChildren();
|
||||
|
@ -115,40 +115,4 @@ public interface OnCompare<Children> extends Serializable {
|
||||
* @return children
|
||||
*/
|
||||
<R, S> Children le(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val);
|
||||
|
||||
/**
|
||||
* ignore
|
||||
*/
|
||||
default <R, S, T> Children between(SFunction<R, ?> column, SFunction<S, ?> val1, SFunction<T, ?> val2) {
|
||||
return between(true, column, val1, val2);
|
||||
}
|
||||
|
||||
/**
|
||||
* BETWEEN 值1 AND 值2
|
||||
*
|
||||
* @param condition 执行条件
|
||||
* @param column 字段
|
||||
* @param val1 值1
|
||||
* @param val2 值2
|
||||
* @return children
|
||||
*/
|
||||
<R, S, T> Children between(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val1, SFunction<T, ?> val2);
|
||||
|
||||
/**
|
||||
* ignore
|
||||
*/
|
||||
default <R, S, T> Children notBetween(SFunction<R, ?> column, SFunction<S, ?> val1, SFunction<T, ?> val2) {
|
||||
return notBetween(true, column, val1, val2);
|
||||
}
|
||||
|
||||
/**
|
||||
* NOT BETWEEN 值1 AND 值2
|
||||
*
|
||||
* @param condition 执行条件
|
||||
* @param column 字段
|
||||
* @param val1 值1
|
||||
* @param val2 值2
|
||||
* @return children
|
||||
*/
|
||||
<R, S, T> Children notBetween(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val1, SFunction<T, ?> val2);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
* @since 1.1.8
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface OnFunction<T> {
|
||||
public interface WrapperFunction<T> {
|
||||
|
||||
MPJLambdaWrapper<T> apply(MPJLambdaWrapper<T> wrapper);
|
||||
}
|
@ -24,7 +24,7 @@ import java.util.stream.Collectors;
|
||||
@Getter
|
||||
public class MybatisLabel<E, T> {
|
||||
|
||||
private final String index = null;
|
||||
private String index;
|
||||
|
||||
private String property;
|
||||
|
||||
@ -53,9 +53,10 @@ public class MybatisLabel<E, T> {
|
||||
* 自动构建
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Builder(String property, Class<E> entityClass, Class<?> javaType) {
|
||||
public Builder(String index, String property, Class<E> entityClass, Class<?> javaType) {
|
||||
this.mybatisLabel = new MybatisLabel<>();
|
||||
mybatisLabel.property = property;
|
||||
mybatisLabel.index = index;
|
||||
mybatisLabel.entityClass = entityClass;
|
||||
mybatisLabel.javaType = javaType;
|
||||
mybatisLabel.ofType = (Class<T>) entityClass;
|
||||
@ -73,9 +74,10 @@ public class MybatisLabel<E, T> {
|
||||
* @param ofType 映射类
|
||||
* @param auto 自动映射数据库实体对应的字段
|
||||
*/
|
||||
public Builder(String property, Class<E> entityClass, Class<?> javaType, Class<T> ofType, boolean auto) {
|
||||
public Builder(String index, String property, Class<E> entityClass, Class<?> javaType, Class<T> ofType, boolean auto) {
|
||||
this.mybatisLabel = new MybatisLabel<>();
|
||||
mybatisLabel.property = property;
|
||||
mybatisLabel.index = index;
|
||||
mybatisLabel.entityClass = entityClass;
|
||||
mybatisLabel.javaType = javaType;
|
||||
mybatisLabel.ofType = ofType;
|
||||
@ -112,67 +114,91 @@ public class MybatisLabel<E, T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public <A, R, B extends Collection<R>> Builder<E, T> collection(Class<A> entityClass, SFunction<T, B> func) {
|
||||
return collection(null, entityClass, func);
|
||||
}
|
||||
|
||||
/**
|
||||
* 嵌套
|
||||
*/
|
||||
public <A, R, B extends Collection<R>> Builder<E, T> collection(Class<A> entityClass, SFunction<T, B> func) {
|
||||
public <A, R, B extends Collection<R>> Builder<E, T> collection(Integer index, Class<A> entityClass, SFunction<T, B> func) {
|
||||
String dtoFieldName = LambdaUtils.getName(func);
|
||||
Class<T> dtoClass = LambdaUtils.getEntityClass(func);
|
||||
Map<String, Field> fieldMap = MPJReflectionKit.getFieldMap(dtoClass);
|
||||
Field field = fieldMap.get(dtoFieldName);
|
||||
Class<?> genericType = MPJReflectionKit.getGenericType(field);
|
||||
MybatisLabel.Builder<A, R> builder;
|
||||
String s = Objects.isNull(index) ? null : index.toString();
|
||||
if (genericType == null || genericType.isAssignableFrom(entityClass)) {
|
||||
//找不到集合泛型 List List<?> List<Object> , 直接查询数据库实体
|
||||
builder = new Builder<>(dtoFieldName, entityClass, field.getType());
|
||||
builder = new Builder<>(s, dtoFieldName, entityClass, field.getType());
|
||||
} else {
|
||||
Class<R> ofType = (Class<R>) genericType;
|
||||
builder = new Builder<>(dtoFieldName, entityClass, field.getType(), ofType, true);
|
||||
builder = new Builder<>(s, dtoFieldName, entityClass, field.getType(), ofType, true);
|
||||
}
|
||||
mybatisLabel.mybatisLabels.add(builder.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
public <A, R, B extends Collection<R>> Builder<E, T> collection(Class<A> entityClass, SFunction<T, B> func, MFunc<Builder<A, R>> mFunc) {
|
||||
return collection(null, entityClass, func, mFunc);
|
||||
}
|
||||
|
||||
/**
|
||||
* 嵌套
|
||||
*/
|
||||
public <A, R, B extends Collection<R>> Builder<E, T> collection(Class<A> entityClass, SFunction<T, B> func, MFunc<Builder<A, R>> mFunc) {
|
||||
public <A, R, B extends Collection<R>> Builder<E, T> collection(Integer index,
|
||||
Class<A> entityClass,
|
||||
SFunction<T, B> func,
|
||||
MFunc<Builder<A, R>> mFunc) {
|
||||
String dtoFieldName = LambdaUtils.getName(func);
|
||||
Class<T> dtoClass = LambdaUtils.getEntityClass(func);
|
||||
Field field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
|
||||
//获取集合泛型
|
||||
Class<?> genericType = MPJReflectionKit.getGenericType(field);
|
||||
Class<R> ofType = (Class<R>) genericType;
|
||||
MybatisLabel.Builder<A, R> builder = new MybatisLabel.Builder<>(dtoFieldName, entityClass, field.getType(), ofType, false);
|
||||
MybatisLabel.Builder<A, R> builder = new MybatisLabel.Builder<>(Objects.isNull(index) ? null : index.toString(),
|
||||
dtoFieldName, entityClass, field.getType(), ofType, false);
|
||||
mybatisLabel.mybatisLabels.add(mFunc.apply(builder).build());
|
||||
return this;
|
||||
}
|
||||
|
||||
public <A, B> Builder<E, T> association(Class<A> child, SFunction<T, B> dtoField) {
|
||||
return association(null, child, dtoField);
|
||||
}
|
||||
|
||||
/**
|
||||
* 嵌套
|
||||
*/
|
||||
public <A, B> Builder<E, T> association(Class<A> child, SFunction<T, B> dtoField) {
|
||||
public <A, B> Builder<E, T> association(Integer index, Class<A> child, SFunction<T, B> dtoField) {
|
||||
Class<T> dtoClass = LambdaUtils.getEntityClass(dtoField);
|
||||
Map<String, Field> fieldMap = MPJReflectionKit.getFieldMap(dtoClass);
|
||||
String dtoFieldName = LambdaUtils.getName(dtoField);
|
||||
Field field = fieldMap.get(dtoFieldName);
|
||||
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
|
||||
MybatisLabel.Builder<A, B> builder;
|
||||
builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), (Class<B>) field.getType(), true);
|
||||
builder = new MybatisLabel.Builder<>(Objects.isNull(index) ? null : index.toString(),
|
||||
dtoFieldName, child, field.getType(), (Class<B>) field.getType(), true);
|
||||
mybatisLabel.mybatisLabels.add(builder.build());
|
||||
return this;
|
||||
}
|
||||
|
||||
public <A, B> Builder<E, T> selectAssociation(Class<A> child, SFunction<T, B> dtoField,
|
||||
MFunc<MybatisLabel.Builder<A, B>> collection) {
|
||||
return selectAssociation(null, child, dtoField, collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* 嵌套
|
||||
*/
|
||||
public <A, B> Builder<E, T> selectAssociation(Class<A> child, SFunction<T, B> dtoField,
|
||||
public <A, B> Builder<E, T> selectAssociation(Integer index, Class<A> child, SFunction<T, B> dtoField,
|
||||
MFunc<MybatisLabel.Builder<A, B>> collection) {
|
||||
String dtoFieldName = LambdaUtils.getName(dtoField);
|
||||
Class<T> dtoClass = LambdaUtils.getEntityClass(dtoField);
|
||||
Field field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
|
||||
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
|
||||
MybatisLabel.Builder<A, B> builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), (Class<B>) child, false);
|
||||
MybatisLabel.Builder<A, B> builder = new MybatisLabel.Builder<>(Objects.isNull(index) ? null : index.toString(),
|
||||
dtoFieldName, child, field.getType(), (Class<B>) child, false);
|
||||
mybatisLabel.mybatisLabels.add(collection.apply(builder).build());
|
||||
return this;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import org.apache.ibatis.type.UnknownTypeHandler;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 缓存列, 普通列
|
||||
* 缓存
|
||||
*
|
||||
* @author yulichang
|
||||
* @since 1.3.10
|
||||
|
@ -45,6 +45,9 @@ public class UserDO {
|
||||
@TableLogic
|
||||
private Boolean del;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String alias;
|
||||
|
||||
@TableField(exist = false)
|
||||
private List<UserDO> children;
|
||||
}
|
||||
|
@ -29,28 +29,29 @@ 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);
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 2, 1, '张三 2', '{"id": 2,"name":"张三 2"}', 1, 0, 'https://url-02', '2022-01-01 12:00:00', false);
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 3, 1, '张三 3', '{"id": 3,"name":"张三 3"}', 1, 0, 'https://url-03', '2022-01-01 12:00:00', false);
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 4, 1, '张三 4', '{"id": 4,"name":"张三 4"}', 1, 0, 'https://url-04', '2022-01-01 12:00:00', false);
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 5, 1, '张三 5', '{"id": 5,"name":"张三 5"}', 1, 0, 'https://url-05', '2022-01-01 12:00:00', false);
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 6, 1, '张三 6', '{"id": 6,"name":"张三 6"}', 1, 0, 'https://url-06', '2022-01-01 12:00:00', false);
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 7, 1, '张三 7', '{"id": 7,"name":"张三 7"}', 1, 0, 'https://url-07', '2022-01-01 12:00:00', false);
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 8, 1, '张三 8', '{"id": 8,"name":"张三 8"}', 1, 0, 'https://url-08', '2022-01-01 12:00:00', false);
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES ( 9, 1, '张三 9', '{"id": 9,"name":"张三 9"}', 1, 0, 'https://url-09', '2022-01-01 12:00:00', false);
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (10, 1, '张三10', '{"id":10,"name":"张三10"}', 1, 0, 'https://url-10', '2022-01-01 12:00:00', true );
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (11, 1, '张三11', '{"id":11,"name":"张三11"}', 1, 0, 'https://url-11', '2022-01-01 12:00:00', true );
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (12, 1, '张三12', '{"id":12,"name":"张三12"}', 1, 0, 'https://url-12', '2022-01-01 12:00:00', true );
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (13, 1, '张三13', '{"id":13,"name":"张三13"}', 1, 0, 'https://url-13', '2022-01-01 12:00:00', true );
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (14, 1, '张三14', '{"id":14,"name":"张三14"}', 1, 0, 'https://url-14', '2022-01-01 12:00:00', true );
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (15, 1, '张三15', '{"id":15,"name":"张三15"}', 1, 0, 'https://url-15', '2022-01-01 12:00:00', true );
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (16, 1, '张三16', '{"id":16,"name":"张三16"}', 1, 0, 'https://url-16', '2022-01-01 12:00:00', true );
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (17, 1, '张三17', '{"id":17,"name":"张三17"}', 1, 0, 'https://url-17', '2022-01-01 12:00:00', true );
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (18, 1, '张三18', '{"id":18,"name":"张三18"}', 1, 0, 'https://url-18', '2022-01-01 12:00:00', true );
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (19, 1, '张三19', '{"id":19,"name":"张三19"}', 1, 0, 'https://url-19', '2022-01-01 12:00:00', true );
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (20, 1, '张三20', '{"id":20,"name":"张三20"}', 1, 0, 'https://url-20', '2022-01-01 12:00:00', true );
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (21, 1, '张三21', '{"id":21,"name":"张三21"}', 1, 0, 'https://url-21', '2022-01-01 12:00:00', true );
|
||||
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, sex, head_img, create_time, del) VALUES (22, 1, '张三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, 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 );
|
||||
|
||||
|
||||
DELETE FROM address;
|
||||
|
@ -114,21 +114,27 @@ class LambdaWrapperTest {
|
||||
void testInner() {
|
||||
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);
|
||||
System.out.println(list);
|
||||
|
||||
MPJLambdaWrapper<UserDO> wrapper1 = new MPJLambdaWrapper<UserDO>()
|
||||
.disableSubLogicDel()
|
||||
.disableLogicDel()
|
||||
.selectAll(UserDO.class)
|
||||
.selectCollection(UserDO.class, UserDO::getChildren)
|
||||
.leftJoin(UserDO.class, UserDO::getPid, UserDO::getId);
|
||||
.selectCollection(1, UserDO.class, UserDO::getChildren, c -> c
|
||||
.collection(2, UserDO.class, UserDO::getChildren))
|
||||
.leftJoin(UserDO.class, UserDO::getPid, UserDO::getId, ext -> ext
|
||||
.selectAs(UserDO::getName, UserDO::getAlias)
|
||||
.leftJoin(UserDO.class, UserDO::getPid, UserDO::getId)
|
||||
.le(UserDO::getId, 5))
|
||||
.le(UserDO::getId, 4);
|
||||
List<UserDO> list1 = userMapper.selectJoinList(UserDO.class, wrapper1);
|
||||
|
||||
System.out.println(list);
|
||||
System.out.println(wrapper1.getSqlSegment());
|
||||
assert "(t1.id <= #{ew.paramNameValuePairs.MPGENVAL1} AND t.id <= #{ew.paramNameValuePairs.MPGENVAL2})".equals(wrapper1.getSqlSegment());
|
||||
System.out.println(list1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,13 +143,13 @@ class LambdaWrapperTest {
|
||||
@Test
|
||||
void testLogicDel() {
|
||||
List<UserDTO> l1 = userMapper.selectJoinList(UserDTO.class, new MPJLambdaWrapper<>());
|
||||
assert l1.size() < 10;
|
||||
assert l1.size() < 15;
|
||||
|
||||
List<UserDTO> l2 = userMapper.selectJoinList(UserDTO.class, new MPJLambdaWrapper<UserDO>()
|
||||
.selectAll(UserDO.class)
|
||||
.select(AddressDO::getAddress)
|
||||
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId));
|
||||
assert l2.size() <= 5;
|
||||
assert l2.size() < 11;
|
||||
|
||||
List<UserDTO> l3 = userMapper.selectJoinList(UserDTO.class, new MPJLambdaWrapper<UserDO>()
|
||||
.disableSubLogicDel()
|
||||
@ -207,8 +213,8 @@ class LambdaWrapperTest {
|
||||
.selectAll(UserDO.class)
|
||||
.select(AddressDO::getAddress)
|
||||
.leftJoin(AddressDO.class, on -> on
|
||||
.eq(UserDO::getId, AddressDO::getUserId)
|
||||
.eq(UserDO::getId, AddressDO::getUserId))
|
||||
.eq(AddressDO::getUserId, UserDO::getId)
|
||||
.eq(AddressDO::getUserId, UserDO::getId))
|
||||
.eq(UserDO::getId, 1)
|
||||
.and(i -> i.eq(UserDO::getImg, "er")
|
||||
.or()
|
||||
|
Loading…
x
Reference in New Issue
Block a user