From a20c6b483ebb6a1423c16968ccaa6b7c327fbd37 Mon Sep 17 00:00:00 2001 From: yulichang <570810310@qq.com> Date: Mon, 13 Mar 2023 11:20:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A1=A8=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../annotation/DynamicTableName.java | 15 +++++ .../yulichang/method/MPJBaseMethod.java | 21 ++++++ .../yulichang/method/SelectJoinCount.java | 2 +- .../yulichang/method/SelectJoinList.java | 2 +- .../yulichang/method/SelectJoinMap.java | 2 +- .../yulichang/method/SelectJoinMaps.java | 2 +- .../yulichang/method/SelectJoinMapsPage.java | 2 +- .../yulichang/method/SelectJoinOne.java | 2 +- .../yulichang/method/SelectJoinPage.java | 2 +- .../yulichang/method/mp/TableAlias.java | 9 +-- .../yulichang/query/MPJQueryWrapper.java | 40 +++++++++++ .../wrapper/MPJAbstractLambdaWrapper.java | 66 +++++++++++++++++++ .../yulichang/wrapper/MPJAbstractWrapper.java | 6 ++ .../yulichang/wrapper/MPJLambdaWrapper.java | 19 +++--- mybatis-plus-join-test/pom.xml | 2 +- .../test/config/MybatisPlusConfig.java | 32 ++++++--- .../yulichang/test/util/ThreadLocalUtils.java | 16 ++++- .../yulichang/test/join/entity/UserDO.java | 2 + .../test/join/LambdaWrapperTest.java | 56 ++++++++++++++-- .../yulichang/test/join/QueryWrapperTest.java | 31 +++++---- 20 files changed, 279 insertions(+), 50 deletions(-) create mode 100644 mybatis-plus-join-annotation/src/main/java/com/github/yulichang/annotation/DynamicTableName.java diff --git a/mybatis-plus-join-annotation/src/main/java/com/github/yulichang/annotation/DynamicTableName.java b/mybatis-plus-join-annotation/src/main/java/com/github/yulichang/annotation/DynamicTableName.java new file mode 100644 index 0000000..daf8fc6 --- /dev/null +++ b/mybatis-plus-join-annotation/src/main/java/com/github/yulichang/annotation/DynamicTableName.java @@ -0,0 +1,15 @@ +package com.github.yulichang.annotation; + +import java.lang.annotation.*; + +/** + * 动态表名注解 + * + * @author yulichang + * @since 1.4.4 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface DynamicTableName { +} diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/MPJBaseMethod.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/MPJBaseMethod.java index 016a091..13d68cf 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/MPJBaseMethod.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/MPJBaseMethod.java @@ -6,8 +6,11 @@ import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.toolkit.Constants; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils; +import com.github.yulichang.annotation.DynamicTableName; import com.github.yulichang.config.ConfigProperties; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.Objects; import static java.util.stream.Collectors.joining; @@ -146,4 +149,22 @@ public interface MPJBaseMethod extends Constants { default String mpjSqlSelectColumns() { return SqlScriptUtils.convertIf("DISTINCT", "ew.selectDistinct", false); } + + /** + * 获取表名 + */ + default String mpjTableName(TableInfo tableInfo) { + DynamicTableName dynamicTableName = tableInfo.getEntityType().getAnnotation(DynamicTableName.class); + if (Objects.isNull(dynamicTableName)) { + return tableInfo.getTableName(); + } + String tableName = tableInfo.getTableName(), encode; + try { + encode = URLEncoder.encode(tableName, "UTF-8"); + } catch (UnsupportedEncodingException e) { + encode = tableName; + } + boolean en = tableName.equals(encode); + return String.format("${ew.getTableName%s(\"%s\")}", en ? "" : "Enc", en ? tableName : encode); + } } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinCount.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinCount.java index a7481b5..6fc295b 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinCount.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinCount.java @@ -26,7 +26,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()); + mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Long.class); } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinList.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinList.java index 6bf39fb..ce5d951 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinList.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinList.java @@ -25,7 +25,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(), sqlDistinct(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class); } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinMap.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinMap.java index a2119ed..2951078 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinMap.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinMap.java @@ -27,7 +27,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(), sqlDistinct(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinMaps.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinMaps.java index 0748e8d..5832ba8 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinMaps.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinMaps.java @@ -27,7 +27,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(), sqlDistinct(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinMapsPage.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinMapsPage.java index 1c3214d..c2ba135 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinMapsPage.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinMapsPage.java @@ -27,7 +27,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(), sqlDistinct(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinOne.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinOne.java index 38bbd31..596c076 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinOne.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinOne.java @@ -25,7 +25,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(), sqlDistinct(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class); } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinPage.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinPage.java index 4d14e10..a7cc5b0 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinPage.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/SelectJoinPage.java @@ -25,7 +25,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(), sqlDistinct(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class); } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/mp/TableAlias.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/mp/TableAlias.java index 8498282..d69bdea 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/mp/TableAlias.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/method/mp/TableAlias.java @@ -15,10 +15,11 @@ import com.github.yulichang.method.MPJBaseMethod; public interface TableAlias extends Constants, MPJBaseMethod { default String getTableName(TableInfo tableInfo) { - String from = SqlScriptUtils.convertIf("${ew.from}", + String from = SqlScriptUtils.convertIf(" ${ew.from}", String.format("%s != null and %s != ''", "ew.from", "ew.from"), true); - String alias = SqlScriptUtils.convertIf("${ew.alias}" + NEWLINE + from, - String.format("%s != null and %s instanceof %s", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), true); - return tableInfo.getTableName() + SPACE + alias; + String alias = SqlScriptUtils.convertChoose( + String.format("%s != null and %s instanceof %s", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()), + mpjTableName(tableInfo) + " ${ew.alias} " + NEWLINE + from, tableInfo.getTableName()); + return SPACE + alias; } } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java index 0aa6947..640c57c 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java @@ -12,11 +12,14 @@ import com.github.yulichang.query.interfaces.StringJoin; import com.github.yulichang.toolkit.MPJWrappers; import com.github.yulichang.toolkit.TableHelper; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -65,6 +68,11 @@ public class MPJQueryWrapper extends AbstractWrapper tableNameFunc; + public MPJQueryWrapper() { super.initNeed(); @@ -238,6 +246,38 @@ public class MPJQueryWrapper extends AbstractWrapper + * @see com.github.yulichang.annotation.DynamicTableName + */ + public MPJQueryWrapper setTableName(Function func) { + this.tableNameFunc = func; + return typedThis; + } + + public String getTableName(String tableName) { + if (this.tableNameFunc == null) { + return tableName; + } + return this.tableNameFunc.apply(tableName); + } + + public String getTableNameEnc(String tableName) { + String decode; + try { + decode = URLDecoder.decode(tableName, "UTF-8"); + } catch (UnsupportedEncodingException e) { + decode = tableName; + } + if (this.tableNameFunc == null) { + return decode; + } + return this.tableNameFunc.apply(decode); + } + /** * 返回一个支持 lambda 函数写法的 wrapper */ diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java index b53b7ef..fbaa173 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJAbstractLambdaWrapper.java @@ -2,20 +2,25 @@ 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.TableInfo; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.github.yulichang.config.ConfigProperties; import com.github.yulichang.toolkit.LambdaUtils; +import com.github.yulichang.toolkit.TableHelper; import com.github.yulichang.toolkit.TableList; import com.github.yulichang.toolkit.support.ColumnCache; import com.github.yulichang.wrapper.enums.PrefixEnum; import com.github.yulichang.wrapper.segments.SelectCache; import lombok.Getter; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; import static java.util.stream.Collectors.joining; @@ -42,6 +47,67 @@ public abstract class MPJAbstractLambdaWrapper tableFunc; + + /** + * 设置表别名 + * 设置表别名注意sql注入问题 + * + * @return 自定义表别名 + */ + public Children setTableName(Function tableFunc) { + if (isMain) { + if (tableFunc != null) { + this.dynamicTableName = true; + this.tableFunc = tableFunc; + } + } else { + this.tableName = tableFunc.apply(this.tableName); + } + return typedThis; + } + + public String getTableName(String tableName) { + if (isMain) { + if (dynamicTableName) { + return tableFunc.apply(tableName); + } + return tableName; + } + return super.getTableName(); + } + + @SuppressWarnings("unused") + public String getTableNameEnc(String tableName) { + Class entityClass = getEntityClass(); + if (entityClass != null) { + TableInfo tableInfo = TableHelper.get(entityClass); + if (tableInfo != null) { + if (dynamicTableName) { + return tableFunc.apply(tableInfo.getTableName()); + } + return tableInfo.getTableName(); + } + } + String decode; + try { + decode = URLDecoder.decode(tableName, "UTF-8"); + } catch (UnsupportedEncodingException e) { + decode = tableName; + } + if (dynamicTableName) { + return tableFunc.apply(decode); + } + return decode; + } @Override protected String columnToString(Integer index, X column, boolean isJoin, PrefixEnum prefixEnum) { diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJAbstractWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJAbstractWrapper.java index ad69195..dc47144 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJAbstractWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJAbstractWrapper.java @@ -85,6 +85,12 @@ public abstract class MPJAbstractWrapper joinClass; + + /** + * 连表表名 + */ + @Getter + protected String tableName; /** * 主表wrapper */ diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java index 80a651f..17948ac 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java @@ -149,7 +149,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq, Map paramNameValuePairs, MergeSegments mergeSegments, SharedString lastSql, SharedString sqlComment, SharedString sqlFirst, - TableList tableList, Integer index, String keyWord, Class joinClass) { + TableList tableList, Integer index, String keyWord, Class joinClass, String tableName) { super.setEntity(entity); super.setEntityClass(entityClass); this.paramNameSeq = paramNameSeq; @@ -163,6 +163,7 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper extends MPJAbstractLambdaWrapper wrapper : onWrappers) { if (StringUtils.isBlank(wrapper.from.getStringValue())) { - TableInfo info = TableHelper.get(wrapper.getJoinClass()); - Assert.notNull(info, "table not find by class <%s>", wrapper.getJoinClass().getSimpleName()); - String tableName = info.getTableName(); value.append(StringPool.SPACE) .append(wrapper.getKeyWord()) .append(StringPool.SPACE) - .append(tableName) + .append(wrapper.getTableName()) .append(StringPool.SPACE) .append(wrapper.hasAlias ? wrapper.alias : (wrapper.alias + wrapper.getIndex())) .append(Constant.ON) @@ -306,13 +304,13 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper instance() { - return instance(index, null, null); + return instance(index, null, null, null); } - protected MPJLambdaWrapper instance(Integer index, String keyWord, Class joinClass) { + protected MPJLambdaWrapper instance(Integer index, String keyWord, Class joinClass, String tableName) { 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, tableName); } @Override @@ -382,8 +380,11 @@ public class MPJLambdaWrapper extends MPJAbstractLambdaWrapper MPJLambdaWrapper join(String keyWord, Class clazz, String tableAlias, BiConsumer, MPJLambdaWrapper> consumer) { Integer oldIndex = this.getIndex(); int newIndex = tableIndex; - MPJLambdaWrapper instance = instance(newIndex, keyWord, clazz); + TableInfo info = TableHelper.get(clazz); + Assert.notNull(info, "table not find by class <%s>", clazz.getSimpleName()); + MPJLambdaWrapper instance = instance(newIndex, keyWord, clazz, info.getTableName()); instance.isNo = true; + instance.isMain = false; onWrappers.add(instance); if (StringUtils.isBlank(tableAlias)) { tableList.put(oldIndex, clazz, false, ConfigProperties.tableAlias, newIndex); diff --git a/mybatis-plus-join-test/pom.xml b/mybatis-plus-join-test/pom.xml index 6e7de01..3b95bf1 100644 --- a/mybatis-plus-join-test/pom.xml +++ b/mybatis-plus-join-test/pom.xml @@ -98,7 +98,7 @@ com.baomidou mybatis-plus-boot-starter - 3.5.3.1 + 3.4.2 org.springframework diff --git a/mybatis-plus-join-test/test-base/src/main/java/com/github/yulichang/test/config/MybatisPlusConfig.java b/mybatis-plus-join-test/test-base/src/main/java/com/github/yulichang/test/config/MybatisPlusConfig.java index 566d2b2..60c12d6 100644 --- a/mybatis-plus-join-test/test-base/src/main/java/com/github/yulichang/test/config/MybatisPlusConfig.java +++ b/mybatis-plus-join-test/test-base/src/main/java/com/github/yulichang/test/config/MybatisPlusConfig.java @@ -5,7 +5,10 @@ import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.github.yulichang.test.util.ThreadLocalUtils; +import lombok.SneakyThrows; import org.apache.ibatis.builder.SqlSourceBuilder; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.executor.statement.StatementHandler; @@ -17,6 +20,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.sql.Connection; +import java.util.List; import java.util.Objects; /** @@ -44,25 +48,30 @@ public class MybatisPlusConfig { public static class SqlInterceptor implements InnerInterceptor { @Override + @SneakyThrows public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { String sql = boundSql.getSql(); String s = ThreadLocalUtils.get(); if (StringUtils.isNotBlank(s)) { - if (!Objects.equals(formatSql(sql), formatSql(s))) { - System.err.println("执行sql: " + SqlSourceBuilder.removeExtraWhitespaces(sql)); - System.err.println("预期sql: " + SqlSourceBuilder.removeExtraWhitespaces(s)); - throw new RuntimeException("sql error"); - } else { + ObjectMapper mapper = new ObjectMapper(); + List sqlList = mapper.readValue(s, new TypeReference>() { + }); + if (sqlList.stream().anyMatch(e -> Objects.equals(formatSql(sql), formatSql(e)))) { System.out.println("==============================================="); System.out.println(); System.out.println("pass"); System.out.println(); System.out.println("==============================================="); + } else { + System.err.println("执行sql: " + SqlSourceBuilder.removeExtraWhitespaces(sql)); + sqlList.forEach(i -> System.err.println("预期sql: " + i)); + throw new RuntimeException("sql error"); } } } @Override + @SneakyThrows public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) { BoundSql boundSql = sh.getBoundSql(); if (boundSql != null && StringUtils.isNotBlank(boundSql.getSql())) { @@ -72,16 +81,19 @@ public class MybatisPlusConfig { } String s = ThreadLocalUtils.get(); if (StringUtils.isNotBlank(s)) { - if (!Objects.equals(formatSql(sql), formatSql(s))) { - System.err.println("执行sql: " + SqlSourceBuilder.removeExtraWhitespaces(sql)); - System.err.println("预期sql: " + SqlSourceBuilder.removeExtraWhitespaces(s)); - throw new RuntimeException("sql error"); - }else { + ObjectMapper mapper = new ObjectMapper(); + List sqlList = mapper.readValue(s, new TypeReference>() { + }); + if (sqlList.stream().anyMatch(e -> Objects.equals(formatSql(sql), formatSql(e)))) { System.out.println("==============================================="); System.out.println(); System.out.println("pass"); System.out.println(); System.out.println("==============================================="); + } else { + System.err.println("执行sql: " + SqlSourceBuilder.removeExtraWhitespaces(sql)); + sqlList.forEach(i -> System.err.println("预期sql: " + i)); + throw new RuntimeException("sql error"); } } } diff --git a/mybatis-plus-join-test/test-base/src/main/java/com/github/yulichang/test/util/ThreadLocalUtils.java b/mybatis-plus-join-test/test-base/src/main/java/com/github/yulichang/test/util/ThreadLocalUtils.java index 8253699..a309fe4 100644 --- a/mybatis-plus-join-test/test-base/src/main/java/com/github/yulichang/test/util/ThreadLocalUtils.java +++ b/mybatis-plus-join-test/test-base/src/main/java/com/github/yulichang/test/util/ThreadLocalUtils.java @@ -1,5 +1,10 @@ package com.github.yulichang.test.util; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.Arrays; + public class ThreadLocalUtils { private final static ThreadLocal userThreadLocal = new ThreadLocal<>(); @@ -7,8 +12,13 @@ public class ThreadLocalUtils { /** * 设置数据到当前线程 */ - public static void set(String sql) { - userThreadLocal.set(sql); + public static void set(String... sql) { + ObjectMapper mapper = new ObjectMapper(); + try { + userThreadLocal.set(mapper.writeValueAsString(Arrays.asList(sql))); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } } /** @@ -16,7 +26,7 @@ public class ThreadLocalUtils { */ public static String get() { String s = userThreadLocal.get(); - set(null); + set(""); return s; } } diff --git a/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/entity/UserDO.java b/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/entity/UserDO.java index 58e4e34..d6d2626 100644 --- a/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/entity/UserDO.java +++ b/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/entity/UserDO.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.github.yulichang.annotation.DynamicTableName; import com.github.yulichang.test.join.enums.Sex; import lombok.Data; import lombok.EqualsAndHashCode; @@ -19,6 +20,7 @@ import java.util.Map; @ToString @Accessors(chain = true) @EqualsAndHashCode(callSuper = true) +@DynamicTableName @TableName(value = "`user`", autoResultMap = true) public class UserDO extends ID implements Serializable { diff --git a/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/LambdaWrapperTest.java b/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/LambdaWrapperTest.java index 34935c8..55ff181 100644 --- a/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/LambdaWrapperTest.java +++ b/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/LambdaWrapperTest.java @@ -15,6 +15,7 @@ import com.github.yulichang.wrapper.MPJLambdaWrapper; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.jdbc.BadSqlGrammarException; import java.sql.Timestamp; import java.util.List; @@ -37,6 +38,7 @@ class LambdaWrapperTest { @Autowired private UserDTOMapper userDTOMapper; + @Test void testJoin() { ThreadLocalUtils.set("SELECT t.id,\n" + @@ -628,7 +630,7 @@ class LambdaWrapperTest { .select(AddressDO.class, p -> true) .leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId) .eq(UserDO::getId, 1); - Page page = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class, wrapper); + IPage page = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class, wrapper); assert page.getRecords().get(0).getAddress() != null; page.getRecords().forEach(System.out::println); } @@ -675,11 +677,15 @@ class LambdaWrapperTest { */ @Test void testFunc() { + ThreadLocalUtils.set("SELECT if(t1.user_id < 5,t1.user_id,t1.user_id + 100) AS id FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.del=false AND t1.del=false"); MPJLambdaWrapper wrapper = new MPJLambdaWrapper() - .selectAll(UserDO.class); + .selectFunc("if(%s < 5,%s,%s + 100)", arg -> arg.accept(AddressDO::getUserId, AddressDO::getUserId, AddressDO::getUserId), UserDO::getId) + .leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId); - List dos = userMapper.selectJoinList(UserDO.class, wrapper); - System.out.println(1); + try { + List dos = userMapper.selectJoinList(UserDO.class, wrapper); + } catch (BadSqlGrammarException ignored) { + } } /** @@ -693,4 +699,46 @@ class LambdaWrapperTest { .orderByDesc(UserDO::getId); List list = userMapper.selectJoinList(UserTTT.class, wrapper); } + + /** + * count + */ + @Test + void testCount() { + ThreadLocalUtils.set( + "SELECT COUNT( * ) AS total FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) LEFT JOIN area t2 ON (t2.id = t1.area_id) WHERE t.del=false AND t1.del=false AND t2.del=false", + "SELECT COUNT( * ) FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) LEFT JOIN area t2 ON (t2.id = t1.area_id) WHERE t.del=false AND t1.del=false AND t2.del=false"); + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId) + .leftJoin(AreaDO.class, AreaDO::getId, AddressDO::getAreaId); + Integer integer = userMapper.selectCount(wrapper); + + ThreadLocalUtils.set("SELECT COUNT( * ) FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) LEFT JOIN area t2 ON (t2.id = t1.area_id) WHERE t.del=false AND t1.del=false AND t2.del=false"); + MPJLambdaWrapper wrapper1 = new MPJLambdaWrapper() + .leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId) + .leftJoin(AreaDO.class, AreaDO::getId, AddressDO::getAreaId); + Long aLong1 = userMapper.selectJoinCount(wrapper1); + } + + + /** + * 动态别名 + */ + @Test + void testTable() { + ThreadLocalUtils.set("SELECT t.id FROM `user`bbbbbbb t LEFT JOIN addressaaaaaaaaaa t1 ON (t1.user_id = t.id) LEFT JOIN area t2 ON (t2.id = t1.area_id) WHERE t.del=false AND t1.del=false AND t2.del=false AND (t.id <= ?) ORDER BY t.id DESC"); + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .select(UserDO::getId) + .leftJoin(AddressDO.class, on -> on + .eq(AddressDO::getUserId, UserDO::getId) + .setTableName(name -> name + "aaaaaaaaaa")) + .leftJoin(AreaDO.class, AreaDO::getId, AddressDO::getAreaId) + .le(UserDO::getId, 10000) + .orderByDesc(UserDO::getId) + .setTableName(name -> name + "bbbbbbb"); + try { + List list = userMapper.selectJoinList(UserDTO.class, wrapper); + } catch (BadSqlGrammarException ignored) { + } + } } diff --git a/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/QueryWrapperTest.java b/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/QueryWrapperTest.java index 8a62eba..b2c6db3 100644 --- a/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/QueryWrapperTest.java +++ b/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/QueryWrapperTest.java @@ -6,8 +6,10 @@ import com.github.yulichang.query.MPJQueryWrapper; import com.github.yulichang.test.join.dto.UserDTO; import com.github.yulichang.test.join.entity.UserDO; import com.github.yulichang.test.join.mapper.UserMapper; +import com.github.yulichang.test.util.ThreadLocalUtils; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.jdbc.BadSqlGrammarException; import javax.annotation.Resource; import java.util.List; @@ -23,18 +25,6 @@ class QueryWrapperTest { */ @Test void test1() { - MPJQueryWrapper last = new MPJQueryWrapper() - .disableLogicDel() - .selectAll(UserDO.class) - .eq("t.id", 1) - .last("LIMIT 1"); - System.out.println(last.getSqlSegment()); - System.out.println(last.isEmptyOfNormal()); - System.out.println(last.nonEmptyOfNormal()); - UserDO userDO = userMapper.selectJoinOne(UserDO.class, last); - - System.out.println(userDO); - UserDTO dto = userMapper.selectJoinOne(UserDTO.class, new MPJQueryWrapper() .selectAll(UserDO.class) .select("name AS nameName") @@ -42,6 +32,23 @@ class QueryWrapperTest { System.out.println(dto); } + /** + * 链表查询 + */ + @Test + void table() { + ThreadLocalUtils.set("SELECT t.id,t.pid,t.`name`,t.`json`,t.sex,t.head_img,t.create_time,t.address_id,t.address_id2,t.del,t.create_by,t.update_by,name AS nameName FROM `user`fwear t WHERE t.del=false LIMIT 1"); + MPJQueryWrapper wrapper = new MPJQueryWrapper() + .selectAll(UserDO.class) + .setTableName(name -> name + "fwear") + .select("name AS nameName") + .last("LIMIT 1"); + try { + userMapper.selectJoinOne(UserDTO.class, wrapper); + } catch (BadSqlGrammarException ignored) { + } + } + @Test void test2() { List userDO = userMapper.selectJoinList(UserDO.class, new MPJQueryWrapper()