diff --git a/pom.xml b/pom.xml index 0cdb9ad..bc8def3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.yulichang mybatis-plus-join - 1.1.8 + 1.2.0.Beta5 mybatis-plus-join An enhanced toolkit of Mybatis-Plus to simplify development. https://github.com/yulichang/mybatis-plus-join @@ -32,13 +32,16 @@ UTF-8 1.8 1.8 + + 1.8 + 1.8 com.baomidou mybatis-plus-boot-starter - 3.4.3 + 3.4.3.2 provided diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java new file mode 100644 index 0000000..654f347 --- /dev/null +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableAliasHelper.java @@ -0,0 +1,66 @@ +package com.baomidou.mybatisplus.core.metadata; + +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.github.yulichang.annotation.MPJTableAlias; +import com.github.yulichang.toolkit.Constant; +import lombok.Data; + +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 全局表别名控制,默认表别名为 t t1 t2 ...
+ * 可以通过@MPJTableAlias注解指定表别名
+ * 仅对MPJLambdaWrapper有效 + * + * @author yulichang + * @see com.github.yulichang.wrapper.MPJLambdaWrapper + * @see MPJTableAlias + * @since 1.2.0 + */ +public class MPJTableAliasHelper { + + private static final Map, TableAlias> CACHE = new ConcurrentHashMap<>(); + + /** + * 用于生成别名的序号 + */ + private static final AtomicInteger index = new AtomicInteger(1); + + public static void init(Class clazz) { + TableAlias as = CACHE.get(clazz); + if (Objects.nonNull(as)) { + return; + } + TableAlias alias = new TableAlias(); + MPJTableAlias tableAlias = clazz.getAnnotation(MPJTableAlias.class); + if (tableAlias != null && StringUtils.isNotBlank(tableAlias.value())) { + alias.setAlias(tableAlias.value()); + } else { + alias.setAlias(Constant.TABLE_ALIAS + index.getAndIncrement()); + } + alias.setAliasDOT(alias.getAlias() + StringPool.DOT); + CACHE.put(clazz, alias); + } + + public static TableAlias get(Class clazz) { + return CACHE.get(clazz); + } + + @Data + public static class TableAlias { + /** + * 表别名 + */ + private String alias; + + /** + * 前缀 + */ + private String aliasDOT; + } + +} diff --git a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java index bfe3773..8b95323 100644 --- a/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java +++ b/src/main/java/com/baomidou/mybatisplus/core/metadata/MPJTableInfoHelper.java @@ -66,6 +66,41 @@ public class MPJTableInfoHelper { return TABLE_INFO_CACHE.get(clazz); } + /** + *

+ * 获取所有实体映射表信息 + *

+ * + * @return 数据库表反射信息集合 + */ + public static List getTableInfos() { + return Collections.unmodifiableList(new ArrayList<>(TABLE_INFO_CACHE.values())); + } + + /** + *

+ * 实体类反射获取表信息【初始化】 + *

+ * + * @param clazz 反射实体类 + * @param mapperClass mapperClass + */ + @SuppressWarnings("unused") + public synchronized static void initTableInfo(MapperBuilderAssistant builderAssistant, Class clazz, Class mapperClass) { + MPJTableInfo targetTableInfo = TABLE_INFO_CACHE.get(clazz); + final Configuration configuration = builderAssistant.getConfiguration(); + if (targetTableInfo != null) { + Configuration oldConfiguration = targetTableInfo.getTableInfo().getConfiguration(); + if (!oldConfiguration.equals(configuration)) { + // 不是同一个 Configuration,进行重新初始化 + initTableInfo(configuration, builderAssistant.getCurrentNamespace(), clazz, mapperClass); + } + return; + } + initTableInfo(configuration, builderAssistant.getCurrentNamespace(), clazz, mapperClass); + } + + /** *

* 获取所有实体映射表信息 diff --git a/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java b/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java new file mode 100644 index 0000000..0a5f067 --- /dev/null +++ b/src/main/java/com/github/yulichang/annotation/MPJTableAlias.java @@ -0,0 +1,25 @@ +package com.github.yulichang.annotation; + +import java.lang.annotation.*; + +/** + * 关联查询时的表别名
+ * 框架默认会随机生成 一般是 t1 t2 t3 ...
+ * 不要在程序中使用随机别名,运行期间是不变的,但是重启就不一定了
+ * 如需使用请配合此注解一起使用
+ *

+ * 这个注解定义的表别名或者随机生成的别名只对MPJLambdaWrapper生效
+ * 对MPJQueryWrapper不生效, + * + * @author yulichang + * @see com.github.yulichang.wrapper.MPJLambdaWrapper + * @see com.github.yulichang.query.MPJQueryWrapper + * @since 1.2.0 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) +public @interface MPJTableAlias { + + String value(); +} diff --git a/src/main/java/com/github/yulichang/method/MPJAbstractMethod.java b/src/main/java/com/github/yulichang/method/MPJAbstractMethod.java index f5a16d9..e40254d 100644 --- a/src/main/java/com/github/yulichang/method/MPJAbstractMethod.java +++ b/src/main/java/com/github/yulichang/method/MPJAbstractMethod.java @@ -1,10 +1,10 @@ package com.github.yulichang.method; import com.baomidou.mybatisplus.core.injector.AbstractMethod; +import com.baomidou.mybatisplus.core.metadata.MPJTableAliasHelper; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils; -import com.github.yulichang.toolkit.Constant; import java.util.ArrayList; import java.util.List; @@ -40,7 +40,7 @@ public abstract class MPJAbstractMethod extends AbstractMethod { String[] columns = selectColumns.split(StringPool.COMMA); List selectColumnList = new ArrayList<>(); for (String c : columns) { - selectColumnList.add(Constant.TABLE_ALIAS + StringPool.DOT + c); + selectColumnList.add(MPJTableAliasHelper.get(table.getEntityType()).getAlias() + StringPool.DOT + c); } selectColumns = String.join(StringPool.COMMA, selectColumnList); } @@ -58,8 +58,9 @@ public abstract class MPJAbstractMethod extends AbstractMethod { SqlScriptUtils.unSafeParam(Q_WRAPPER_SQL_SELECT), ASTERISK); } - protected String sqlAlias() { - return SqlScriptUtils.convertIf("${ew.alias}", String.format("%s != null and %s != ''", "ew.alias", "ew.alias"), false); + protected String sqlAlias(Class modelClass) { + return SqlScriptUtils.convertChoose(String.format("%s != null and %s != ''", "ew.autoAlias", "ew.autoAlias"), + MPJTableAliasHelper.get(modelClass).getAlias(), "${ew.alias}"); } protected String sqlFrom() { diff --git a/src/main/java/com/github/yulichang/method/SelectJoinCount.java b/src/main/java/com/github/yulichang/method/SelectJoinCount.java index 628d277..c45a010 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinCount.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinCount.java @@ -17,7 +17,7 @@ public class SelectJoinCount extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_COUNT; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlCount(), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Integer.class); } diff --git a/src/main/java/com/github/yulichang/method/SelectJoinList.java b/src/main/java/com/github/yulichang/method/SelectJoinList.java index 6918275..dc1452d 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinList.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinList.java @@ -15,7 +15,7 @@ public class SelectJoinList extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_LIST; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class); } diff --git a/src/main/java/com/github/yulichang/method/SelectJoinMap.java b/src/main/java/com/github/yulichang/method/SelectJoinMap.java index efffa5f..c457b20 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinMap.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinMap.java @@ -17,7 +17,7 @@ public class SelectJoinMap extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_MAP; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/src/main/java/com/github/yulichang/method/SelectJoinMaps.java b/src/main/java/com/github/yulichang/method/SelectJoinMaps.java index 9aa3ca7..5445852 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinMaps.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinMaps.java @@ -17,7 +17,7 @@ public class SelectJoinMaps extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_MAPS; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/src/main/java/com/github/yulichang/method/SelectJoinMapsPage.java b/src/main/java/com/github/yulichang/method/SelectJoinMapsPage.java index 2ca6219..5bb24b8 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinMapsPage.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinMapsPage.java @@ -17,7 +17,7 @@ public class SelectJoinMapsPage extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_MAPS_PAGE; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/src/main/java/com/github/yulichang/method/SelectJoinOne.java b/src/main/java/com/github/yulichang/method/SelectJoinOne.java index 3d37df4..93c2728 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinOne.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinOne.java @@ -15,7 +15,7 @@ public class SelectJoinOne extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_ONE; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class); } diff --git a/src/main/java/com/github/yulichang/method/SelectJoinPage.java b/src/main/java/com/github/yulichang/method/SelectJoinPage.java index 0f9a03b..44d8d11 100644 --- a/src/main/java/com/github/yulichang/method/SelectJoinPage.java +++ b/src/main/java/com/github/yulichang/method/SelectJoinPage.java @@ -15,7 +15,7 @@ public class SelectJoinPage extends MPJAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_PAGE; String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), sqlAlias(modelClass), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class); } diff --git a/src/main/java/com/github/yulichang/toolkit/Constant.java b/src/main/java/com/github/yulichang/toolkit/Constant.java index 31854d7..4520fb3 100644 --- a/src/main/java/com/github/yulichang/toolkit/Constant.java +++ b/src/main/java/com/github/yulichang/toolkit/Constant.java @@ -11,8 +11,6 @@ public interface Constant { */ String TABLE_ALIAS = "t"; - String AS = " AS "; - String ON = " ON "; String JOIN = "JOIN"; @@ -39,9 +37,4 @@ public interface Constant { * " INNER JOIN " */ String INNER_JOIN = StringPool.SPACE + INNER + StringPool.SPACE + JOIN + StringPool.SPACE; - - /** - * " t" - */ - String SPACE_TABLE_ALIAS = StringPool.SPACE + Constant.TABLE_ALIAS; } diff --git a/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java b/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java index 9b9ece8..d4ab2f3 100644 --- a/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java +++ b/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java @@ -1,15 +1,14 @@ package com.github.yulichang.wrapper; +import com.baomidou.mybatisplus.core.metadata.MPJTableAliasHelper; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; -import com.github.yulichang.toolkit.Constant; import com.github.yulichang.toolkit.LambdaUtils; import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import java.util.Objects; import static java.util.stream.Collectors.joining; @@ -20,12 +19,6 @@ import static java.util.stream.Collectors.joining; */ public abstract class MPJAbstractLambdaWrapper> extends MPJAbstractWrapper { - - /** - * 关联的表 - */ - protected Map, Integer> subTable = new HashMap<>(); - /** * 缓存字段 */ @@ -33,7 +26,13 @@ public abstract class MPJAbstractLambdaWrapper String columnToString(X column) { - return columnToString((SFunction) column); + return columnToString((SFunction) column, hasAlias || entityClass != + LambdaUtils.getEntityClass((SFunction) column)); + } + + @Override + protected String columnToString(X column, boolean hasAlias) { + return columnToString((SFunction) column, hasAlias); } @Override @@ -42,9 +41,9 @@ public abstract class MPJAbstractLambdaWrapper columnToString((SFunction) i)).collect(joining(StringPool.COMMA)); } - protected String columnToString(SFunction column) { - return Constant.TABLE_ALIAS + getDefault(subTable.get(LambdaUtils.getEntityClass(column))) + StringPool.DOT + - getCache(column).getColumn(); + protected String columnToString(SFunction column, boolean hasAlias) { + return (hasAlias ? MPJTableAliasHelper.get(LambdaUtils.getEntityClass(column)).getAliasDOT() : + StringPool.EMPTY) + getCache(column).getColumn(); } protected ColumnCache getCache(SFunction fn) { @@ -56,12 +55,4 @@ public abstract class MPJAbstractLambdaWrapper> extends Wrapper implements Compare, Nested, Join, Func, OnCompare { + + /** + * 是否使用别名 + */ + protected boolean hasAlias; + /** * 占位符 */ @@ -51,7 +59,7 @@ public abstract class MPJAbstractWrapper entityClass; + protected Class entityClass; @Override public T getEntity() { return entity; } - public Children setEntity(T entity) { - this.entity = entity; - return typedThis; - } - - public Class getEntityClass() { - if (entityClass == null && entity != null) { - entityClass = (Class) entity.getClass(); - } - return entityClass; - } - - public Children setEntityClass(Class entityClass) { - if (entityClass != null) { - this.entityClass = entityClass; - } - return typedThis; - } - @Override public Children allEq(boolean condition, Map, V> params, boolean null2IsNull) { if (condition && CollectionUtils.isNotEmpty(params)) { @@ -329,7 +318,6 @@ public abstract class MPJAbstractWrapper SFunction columnSqlInjectFilter(SFunction column) { return column; @@ -384,9 +372,11 @@ public abstract class MPJAbstractWrapper formatParam(null, val))); } - protected Children addCondition(boolean condition, SFunction column, SqlKeyword sqlKeyword, SFunction val) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword, - columnToSqlSegment(val))); + protected Children addCondition(boolean condition, SFunction column, SqlKeyword sqlKeyword, + SFunction val) { + return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column, hasAlias || entityClass != + LambdaUtils.getEntityClass(column)), sqlKeyword, columnToSqlSegment(val, hasAlias || + entityClass != LambdaUtils.getEntityClass(val)))); } /** @@ -417,6 +407,7 @@ public abstract class MPJAbstractWrapper columnToString(column); } + protected final ISqlSegment columnToSqlSegment(SFunction column, boolean hasAlias) { + return () -> columnToString(column, hasAlias); + } + /** * 获取 columnName */ @@ -579,6 +574,10 @@ public abstract class MPJAbstractWrapper String columnToString(X column, boolean hasAlias) { + return (String) column; + } + /** * 多字段转换为逗号 "," 分割字符串 * @@ -634,36 +633,4 @@ public abstract class MPJAbstractWrapper Children le(boolean condition, SFunction column, SFunction val) { return addCondition(condition, column, LE, val); } - - @Override - public Children between(boolean condition, SFunction column, SFunction val1, SFunction val2) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN, - columnToSqlSegment(val1), AND, columnToSqlSegment(val2))); - } - - public Children between(boolean condition, SFunction column, Object val1, SFunction val2) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN, - () -> formatParam(null, val1), AND, columnToSqlSegment(val2))); - } - - public Children between(boolean condition, SFunction column, SFunction val1, Object val2) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN, - columnToSqlSegment(val1), AND, () -> formatParam(null, val2))); - } - - @Override - public Children notBetween(boolean condition, SFunction column, SFunction val1, SFunction val2) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_BETWEEN, - columnToSqlSegment(val1), AND, columnToSqlSegment(val2))); - } - - public Children notBetween(boolean condition, SFunction column, Object val1, SFunction val2) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_BETWEEN, - () -> formatParam(null, val1), AND, columnToSqlSegment(val2))); - } - - public Children notBetween(boolean condition, SFunction column, SFunction val1, Object val2) { - return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_BETWEEN, - columnToSqlSegment(val1), AND, () -> formatParam(null, val2))); - } } diff --git a/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java b/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java index d63c9dc..571ac51 100644 --- a/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java +++ b/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java @@ -2,9 +2,7 @@ package com.github.yulichang.wrapper; import com.baomidou.mybatisplus.core.conditions.SharedString; import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments; -import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; -import com.baomidou.mybatisplus.core.metadata.TableInfo; -import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; +import com.baomidou.mybatisplus.core.metadata.*; import com.baomidou.mybatisplus.core.toolkit.*; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.github.yulichang.toolkit.Constant; @@ -13,13 +11,10 @@ import com.github.yulichang.wrapper.enums.BaseFuncEnum; import com.github.yulichang.wrapper.interfaces.LambdaJoin; import com.github.yulichang.wrapper.interfaces.Query; import com.github.yulichang.wrapper.interfaces.on.OnFunction; -import lombok.Data; -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.function.Predicate; import java.util.stream.Collectors; @@ -33,61 +28,40 @@ import java.util.stream.Collectors; * @author yulichang * @see com.github.yulichang.toolkit.Wrappers */ -@SuppressWarnings("all") +@SuppressWarnings("unused") public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper> implements Query>, LambdaJoin> { /** * 查询字段 sql */ - private SharedString sqlSelect = new SharedString(); + private final SharedString sqlSelect = new SharedString(); /** * 查询表 */ private final SharedString from = new SharedString(); - /** - * 主表别名 - */ - private final SharedString alias = new SharedString(Constant.TABLE_ALIAS); - /** * 查询的字段 */ - private final List selectColumns = new ArrayList<>(); + private final List selectColumns = new ArrayList<>(); /** * 忽略查询的字段 */ - private final List ignoreColumns = new ArrayList<>(); - - /** - * 表序号 - */ - private int tableIndex = 1; + private final List ignoreColumns = new ArrayList<>(); /** * ON sql wrapper集合 */ - private final List> onWrappers = new ArrayList<>(); - - /** - * 连表关键字 on 条件 func 使用 - */ - @Getter - private String keyWord; - - /** - * 连表实体类 on 条件 func 使用 - */ - @Getter - private Class joinClass; + private final List joinSql = new ArrayList<>(); /** * 不建议直接 new 该实例,使用 Wrappers.lambdaQuery() */ public MPJLambdaWrapper() { + this.hasAlias = true; super.initNeed(); } @@ -95,22 +69,27 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq, + MPJLambdaWrapper(Class entityClass, AtomicInteger paramNameSeq, Map paramNameValuePairs, MergeSegments mergeSegments, - SharedString lastSql, SharedString sqlComment, SharedString sqlFirst, - Map, Integer> subTable, String keyWord, Class joinClass) { - super.setEntity(entity); - super.setEntityClass(entityClass); + SharedString lastSql, SharedString sqlComment, SharedString sqlFirst, boolean hasAlias) { + this.entityClass = entityClass; this.paramNameSeq = paramNameSeq; this.paramNameValuePairs = paramNameValuePairs; this.expression = mergeSegments; - this.sqlSelect = sqlSelect; this.lastSql = lastSql; this.sqlComment = sqlComment; this.sqlFirst = sqlFirst; - this.subTable = subTable; - this.keyWord = keyWord; - this.joinClass = joinClass; + this.hasAlias = hasAlias; + } + + @Override + protected MPJLambdaWrapper instance() { + return instance(true, null); + } + + protected MPJLambdaWrapper instance(boolean hasAlias, Class entityClass) { + return new MPJLambdaWrapper<>(entityClass, paramNameSeq, paramNameValuePairs, new MergeSegments(), + SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), hasAlias); } @Override @@ -118,7 +97,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper MPJLambdaWrapper select(SFunction... columns) { if (ArrayUtils.isNotEmpty(columns)) { for (SFunction s : columns) { - selectColumns.add(SelectColumn.of(LambdaUtils.getEntityClass(s), getCache(s).getColumn())); + selectColumns.add(getThisAlias(s) + getCache(s).getColumn()); } } return typedThis; @@ -128,20 +107,23 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper MPJLambdaWrapper select(Class entityClass, Predicate predicate) { TableInfo info = TableInfoHelper.getTableInfo(entityClass); Assert.notNull(info, "table can not be find"); - info.getFieldList().stream().filter(predicate).collect(Collectors.toList()).forEach( - i -> selectColumns.add(SelectColumn.of(entityClass, i.getColumn()))); + MPJTableAliasHelper.TableAlias alias = MPJTableAliasHelper.get(entityClass); + info.getFieldList().stream().filter(predicate).collect(Collectors.toList()).forEach(i -> + selectColumns.add((hasAlias ? alias.getAliasDOT() : StringPool.EMPTY) + i.getColumn())); return typedThis; } @Override public MPJLambdaWrapper selectAs(SFunction column, String alias) { - selectColumns.add(SelectColumn.of(LambdaUtils.getEntityClass(column), getCache(column).getColumn(), alias)); + selectColumns.add(getThisAlias(column) + getCache(column).getColumn() + Constants.AS + alias); return typedThis; } - public MPJLambdaWrapper selectFunc(boolean condition, BaseFuncEnum funcEnum, SFunction column, String alias) { + public MPJLambdaWrapper selectFunc(boolean condition, BaseFuncEnum funcEnum, SFunction column, + String alias) { if (condition) { - selectColumns.add(SelectColumn.of(LambdaUtils.getEntityClass(column), getCache(column).getColumn(), alias, funcEnum)); + selectColumns.add(String.format(funcEnum.getSql(), getThisAlias(column) + getCache(column).getColumn()) + + Constants.AS + alias); } return typedThis; } @@ -149,7 +131,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper selectFunc(boolean condition, BaseFuncEnum funcEnum, Object column, String alias) { if (condition) { - selectColumns.add(SelectColumn.of(null, column.toString(), alias, funcEnum)); + selectColumns.add(String.format(funcEnum.getSql(), column.toString()) + Constants.AS + alias); } return typedThis; } @@ -157,11 +139,12 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper selectAll(Class clazz) { TableInfo info = TableInfoHelper.getTableInfo(clazz); Assert.notNull(info, "table can not be find -> %s", clazz); + String dot = hasAlias ? MPJTableAliasHelper.get(clazz).getAliasDOT() : StringPool.EMPTY; if (info.havePK()) { - selectColumns.add(SelectColumn.of(clazz, info.getKeyColumn())); + selectColumns.add(dot + info.getKeyColumn()); } - info.getFieldList().forEach(c -> - selectColumns.add(SelectColumn.of(clazz, c.getColumn()))); + info.getFieldList().stream().filter(TableFieldInfo::isSelect).forEach(c -> + selectColumns.add(dot + c.getColumn())); return typedThis; } @@ -170,12 +153,21 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper MPJLambdaWrapper selectIgnore(SFunction... columns) { if (ArrayUtils.isNotEmpty(columns)) { for (SFunction s : columns) { - ignoreColumns.add(SelectColumn.of(LambdaUtils.getEntityClass(s), getCache(s).getColumn())); + ignoreColumns.add(getThisAlias(s) + getCache(s).getColumn()); } } return typedThis; } + + @Override + public MPJLambdaWrapper selectQuery(Class clazz, OnFunction function, String alias) { + MPJLambdaWrapper apply = function.apply(instance(false, clazz)); + selectColumns.add(String.format("(SELECT %s FROM %s %s)", apply.getSqlSelect(), + TableInfoHelper.getTableInfo(clazz).getTableName(), apply.getCustomSqlSegment()) + Constants.AS + alias); + return this; + } + /** * 查询条件 SQL 片段 */ @@ -183,15 +175,9 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper c.getFuncEnum() == null && ignoreColumns.stream().anyMatch(i -> - i.getClazz() == c.getClazz() && Objects.equals(c.getColumnName(), i.getColumnName()))); + selectColumns.removeIf(ignoreColumns::contains); } - String s = selectColumns.stream().map(i -> { - String str = Constant.TABLE_ALIAS + getDefault(subTable.get(i.getClazz())) + StringPool.DOT + i.getColumnName(); - return (i.getFuncEnum() == null ? str : String.format(i.getFuncEnum().getSql(), str)) + - (StringUtils.isBlank(i.getAlias()) ? StringPool.EMPTY : (Constant.AS + i.getAlias())); - }).collect(Collectors.joining(StringPool.COMMA)); - sqlSelect.setStringValue(s); + sqlSelect.setStringValue(String.join(StringPool.COMMA, selectColumns)); } return sqlSelect.getStringValue(); } @@ -201,39 +187,15 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper wrapper : onWrappers) { - String tableName = TableInfoHelper.getTableInfo(wrapper.getJoinClass()).getTableName(); - value.append(wrapper.getKeyWord()) - .append(tableName) - .append(Constant.SPACE_TABLE_ALIAS) - .append(subTable.get(wrapper.getJoinClass())) - .append(Constant.ON) - .append(wrapper.getExpression().getNormal().getSqlSegment()); - } - from.setStringValue(value.toString()); + from.setStringValue(String.join(StringPool.SPACE, joinSql)); } return from.getStringValue(); } - public String getAlias() { - return alias.getStringValue(); + public boolean getAutoAlias() { + return true; } - /** - * 用于生成嵌套 sql - *

故 sqlSelect 不向下传递

- */ - @Override - protected MPJLambdaWrapper instance() { - return instance(null, null); - } - - protected MPJLambdaWrapper instance(String keyWord, Class joinClass) { - return new MPJLambdaWrapper<>(getEntity(), getEntityClass(), null, paramNameSeq, paramNameValuePairs, - new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), - this.subTable, keyWord, joinClass); - } @Override public void clear() { @@ -242,68 +204,21 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper MPJLambdaWrapper join(String keyWord, boolean condition, Class clazz, OnFunction function) { if (condition) { - MPJLambdaWrapper apply = function.apply(instance(keyWord, clazz)); - onWrappers.add(apply); - subTable.put(clazz, tableIndex); - tableIndex++; + joinSql.add(keyWord + TableInfoHelper.getTableInfo(clazz).getTableName() + + Constants.SPACE + MPJTableAliasHelper.get(clazz).getAlias() + + Constant.ON + function.apply(instance()).getExpression().getNormal().getSqlSegment()); } return typedThis; } - /** - * select字段 - */ - @Data - public static class SelectColumn { - - /** - * 字段实体类 - */ - private Class clazz; - - /** - * 数据库字段名 - */ - private String columnName; - - /** - * 字段别名 - */ - private String alias; - - /** - * 字段函数 - */ - private BaseFuncEnum funcEnum; - - /** - * 自定义函数填充参数 - */ - private List> funcArgs; - - private SelectColumn(Class clazz, String columnName, String alias, BaseFuncEnum funcEnum) { - this.clazz = clazz; - this.columnName = columnName; - this.alias = alias; - this.funcEnum = funcEnum; - } - - public static SelectColumn of(Class clazz, String columnName) { - return new SelectColumn(clazz, columnName, null, null); - } - - public static SelectColumn of(Class clazz, String columnName, String alias) { - return new SelectColumn(clazz, columnName, alias, null); - } - - public static SelectColumn of(Class clazz, String columnName, String alias, BaseFuncEnum funcEnum) { - return new SelectColumn(clazz, columnName, alias, funcEnum); - } + private String getThisAlias(SFunction function) { + return hasAlias ? MPJTableAliasHelper.get(LambdaUtils.getEntityClass(function)).getAliasDOT() : + StringPool.EMPTY; } } diff --git a/src/main/java/com/github/yulichang/wrapper/interfaces/Query.java b/src/main/java/com/github/yulichang/wrapper/interfaces/Query.java index 6557c10..66adf65 100644 --- a/src/main/java/com/github/yulichang/wrapper/interfaces/Query.java +++ b/src/main/java/com/github/yulichang/wrapper/interfaces/Query.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.github.yulichang.toolkit.LambdaUtils; import com.github.yulichang.wrapper.enums.BaseFuncEnum; import com.github.yulichang.wrapper.enums.DefaultFuncEnum; +import com.github.yulichang.wrapper.interfaces.on.OnFunction; import java.io.Serializable; import java.util.function.Predicate; @@ -51,6 +52,22 @@ public interface Query extends Serializable { */ Children selectAs(SFunction column, String alias); + /** + * 子查询 + * + * @param clazz 查询的类 + * @param function 查询lambda + * @param alias 别名 + */ + Children selectQuery(Class clazz, OnFunction function, String alias); + + /** + * ignore + */ + default Children selectQuery(Class clazz, OnFunction function, SFunction alias) { + return selectQuery(clazz, function, LambdaUtils.getName(alias)); + } + /** * 聚合函数查询 * diff --git a/src/main/java/com/github/yulichang/wrapper/interfaces/on/OnCompare.java b/src/main/java/com/github/yulichang/wrapper/interfaces/on/OnCompare.java index 00d6166..0113cb7 100644 --- a/src/main/java/com/github/yulichang/wrapper/interfaces/on/OnCompare.java +++ b/src/main/java/com/github/yulichang/wrapper/interfaces/on/OnCompare.java @@ -115,40 +115,4 @@ public interface OnCompare extends Serializable { * @return children */ Children le(boolean condition, SFunction column, SFunction val); - - /** - * ignore - */ - default Children between(SFunction column, SFunction val1, SFunction val2) { - return between(true, column, val1, val2); - } - - /** - * BETWEEN 值1 AND 值2 - * - * @param condition 执行条件 - * @param column 字段 - * @param val1 值1 - * @param val2 值2 - * @return children - */ - Children between(boolean condition, SFunction column, SFunction val1, SFunction val2); - - /** - * ignore - */ - default Children notBetween(SFunction column, SFunction val1, SFunction val2) { - return notBetween(true, column, val1, val2); - } - - /** - * NOT BETWEEN 值1 AND 值2 - * - * @param condition 执行条件 - * @param column 字段 - * @param val1 值1 - * @param val2 值2 - * @return children - */ - Children notBetween(boolean condition, SFunction column, SFunction val1, SFunction val2); }