Browse Source

Merge remote-tracking branch 'upstream/3.0' into 3.0

liuyao 5 years ago
parent
commit
22d52b05c7
52 changed files with 460 additions and 127 deletions
  1. 2 0
      README-zh.md
  2. 1 1
      build.gradle
  3. 34 3
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/AbstractWrapper.java
  4. 2 0
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/Wrapper.java
  5. 9 0
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/interfaces/Func.java
  6. 16 0
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/interfaces/Join.java
  7. 3 2
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/query/LambdaQueryWrapper.java
  8. 4 3
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/query/QueryWrapper.java
  9. 3 2
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/update/LambdaUpdateWrapper.java
  10. 5 3
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/update/UpdateWrapper.java
  11. 10 16
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/enums/SqlMethod.java
  12. 2 3
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/executor/MybatisCachingExecutor.java
  13. 19 6
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/AbstractMethod.java
  14. 1 1
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectBatchByIds.java
  15. 3 3
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectById.java
  16. 10 1
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectCount.java
  17. 7 3
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectList.java
  18. 7 3
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectMaps.java
  19. 7 3
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectMapsPage.java
  20. 7 3
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectObjs.java
  21. 8 3
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectOne.java
  22. 7 3
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectPage.java
  23. 10 0
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableFieldInfo.java
  24. 13 6
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableInfoHelper.java
  25. 4 0
      mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/Constants.java
  26. 10 10
      mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/MybatisDefaultParameterHandlerTest.java
  27. 3 1
      mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/test/EncryptTest.java
  28. 3 1
      mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/test/WrapperTest.java
  29. 12 0
      mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/conditions/AbstractChainWrapper.java
  30. 0 1
      mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/injector/methods/Upsert.java
  31. 2 2
      mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/IllegalSQLInterceptor.java
  32. 3 7
      mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/OptimisticLockerInterceptor.java
  33. 3 2
      mybatis-plus-extension/src/main/kotlin/com/baomidou/mybatisplus/extension/kotlin/KtQueryWrapper.kt
  34. 4 3
      mybatis-plus-extension/src/main/kotlin/com/baomidou/mybatisplus/extension/kotlin/KtUpdateWrapper.kt
  35. 8 8
      mybatis-plus-extension/src/test/java/com/baomidou/mybatisplus/extension/plugins/pagination/SelectBodyToPlainSelectTest.java
  36. 3 1
      mybatis-plus-extension/src/test/kotlin/com/baomidou/mybatisplus/extension/kotlin/WrapperTest.kt
  37. 8 7
      mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/config/StrategyConfig.java
  38. 9 9
      mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/config/builder/ConfigBuilder.java
  39. 4 2
      mybatis-plus-generator/src/test/java/com/baomidou/mybatisplus/test/generator/H2CodeGeneratorTest.java
  40. 3 1
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/SampleTest.java
  41. 0 1
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/config/MybatisPlusConfig.java
  42. 39 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/GenericIdTest.java
  43. 41 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/MybatisPlusConfig.java
  44. 18 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/entity/LongEntity.java
  45. 18 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/entity/StringEntity.java
  46. 15 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/entity/SuperEntity.java
  47. 14 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/mapper/LongEntityMapper.java
  48. 14 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/mapper/StringEntityMapper.java
  49. 2 2
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/tenant/TenantTest.java
  50. 4 1
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/mysql/SelectCountDistinctTest.java
  51. 14 0
      mybatis-plus/src/test/resources/issues/genericid/spring.xml
  52. 12 0
      mybatis-plus/src/test/resources/issues/genericid/sql/init.ddl.sql

+ 2 - 0
README-zh.md

@@ -73,6 +73,8 @@ Mybatis 增强工具包 - 只做增强不做改变,简化`CRUD`操作
 - [基于Hibernate扩展 Hibernate-Plus](https://gitee.com/baomidou/hibernate-plus)
 
 # 王者荣耀
+![MPTrophy](https://images.gitee.com/uploads/images/2019/1221/222621_5e22d783_12260.jpeg)
+
 ![MPTrophy](https://images.gitee.com/uploads/images/2018/1218/151845_f562bcb5_12260.png)
 
 ![MPTrophy](https://gitee.com/uploads/images/2018/0102/101803_2fdba060_12260.jpeg)

+ 1 - 1
build.gradle

@@ -85,7 +85,7 @@ ext {
 
 allprojects {
     group = 'com.baomidou'
-    version = "3.3.1.3-SNAPSHOT"
+    version = "3.3.1.5-SNAPSHOT"
 }
 
 description = "Mybatis 增强工具包 - 只做增强不做改变,简化CRUD操作"

+ 34 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/AbstractWrapper.java

@@ -63,6 +63,11 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
      */
     protected SharedString sqlComment;
     /**
+     * SQL起始语句
+     */
+    protected SharedString sqlFirst;
+    /**
+     * ß
      * 数据库表映射实体类
      */
     private T entity;
@@ -232,6 +237,14 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
         return typedThis;
     }
 
+    @Override
+    public Children first(boolean condition, String firstSql) {
+        if (condition) {
+            this.sqlFirst.setStringValue(firstSql);
+        }
+        return typedThis;
+    }
+
     @Override
     public Children exists(boolean condition, String existsSql) {
         return doIt(condition, EXISTS, () -> String.format("(%s)", existsSql));
@@ -298,6 +311,12 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
         return doIt(condition, HAVING, () -> formatSqlIfNeed(condition, sqlHaving, params));
     }
 
+    @Override
+    public Children func(Consumer<Children> consumer) {
+        consumer.accept(typedThis);
+        return typedThis;
+    }
+
     /**
      * 内部自用
      * <p>NOT 关键词</p>
@@ -340,9 +359,12 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
      * @param condition 查询条件值
      */
     protected Children addNestedCondition(boolean condition, Consumer<Children> consumer) {
-        final Children instance = instance();
-        consumer.accept(instance);
-        return doIt(condition, LEFT_BRACKET, instance, RIGHT_BRACKET);
+        if (condition) {
+            final Children instance = instance();
+            consumer.accept(instance);
+            return doIt(true, LEFT_BRACKET, instance, RIGHT_BRACKET);
+        }
+        return typedThis;
     }
 
     /**
@@ -413,6 +435,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
         expression = new MergeSegments();
         lastSql = SharedString.emptyString();
         sqlComment = SharedString.emptyString();
+        sqlFirst = SharedString.emptyString();
     }
 
     /**
@@ -449,6 +472,14 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
         return null;
     }
 
+    @Override
+    public String getSqlFirst() {
+        if (StringUtils.isNotBlank(sqlFirst.getStringValue())) {
+            return StringEscape.escapeRawString(sqlFirst.getStringValue());
+        }
+        return null;
+    }
+
     @Override
     public MergeSegments getExpression() {
         return expression;

+ 2 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/Wrapper.java

@@ -52,6 +52,8 @@ public abstract class Wrapper<T> implements ISqlSegment {
         return null;
     }
 
+    public String getSqlFirst() { return null; }
+
     /**
      * 获取 MergeSegments
      */

+ 9 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/interfaces/Func.java

@@ -19,6 +19,7 @@ import java.io.Serializable;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Optional;
+import java.util.function.Consumer;
 
 import static java.util.stream.Collectors.toList;
 
@@ -292,4 +293,12 @@ public interface Func<Children, R> extends Serializable {
      * @return children
      */
     Children having(boolean condition, String sqlHaving, Object... params);
+
+    /**
+     * 消费函数
+     *
+     * @param consumer 消费函数
+     * @return children
+     */
+    Children func(Consumer<Children> consumer);
 }

+ 16 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/interfaces/Join.java

@@ -94,6 +94,22 @@ public interface Join<Children> extends Serializable {
      */
     Children comment(boolean condition, String comment);
 
+    /**
+     * ignore
+     */
+    default Children first(String firstSql) {
+        return first(true, firstSql);
+    }
+
+    /**
+     * sql 起始句(会拼接在SQL语句的起始处)
+     *
+     * @param condition 执行条件
+     * @param firstSql  起始语句
+     * @return children
+     */
+    Children first(boolean condition, String firstSql);
+
     /**
      * ignore
      */

+ 3 - 2
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/query/LambdaQueryWrapper.java

@@ -70,7 +70,7 @@ public class LambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, LambdaQueryW
      */
     LambdaQueryWrapper(T entity, Class<T> entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq,
                        Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments,
-                       SharedString lastSql, SharedString sqlComment) {
+                       SharedString lastSql, SharedString sqlComment, SharedString sqlFirst) {
         this.setEntity(entity);
         this.setEntityClass(entityClass);
         this.paramNameSeq = paramNameSeq;
@@ -79,6 +79,7 @@ public class LambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, LambdaQueryW
         this.sqlSelect = sqlSelect;
         this.lastSql = lastSql;
         this.sqlComment = sqlComment;
+        this.sqlFirst = sqlFirst;
     }
 
     /**
@@ -125,6 +126,6 @@ public class LambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, LambdaQueryW
     @Override
     protected LambdaQueryWrapper<T> instance() {
         return new LambdaQueryWrapper<>(getEntity(), getEntityClass(), null, paramNameSeq, paramNameValuePairs,
-            new MergeSegments(), SharedString.emptyString(), SharedString.emptyString());
+            new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString());
     }
 }

+ 4 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/query/QueryWrapper.java

@@ -64,7 +64,7 @@ public class QueryWrapper<T> extends AbstractWrapper<T, String, QueryWrapper<T>>
      */
     private QueryWrapper(T entity, Class<T> entityClass, AtomicInteger paramNameSeq,
                          Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments,
-                         SharedString lastSql, SharedString sqlComment) {
+                         SharedString lastSql, SharedString sqlComment, SharedString sqlFirst) {
         this.setEntity(entity);
         this.setEntityClass(entityClass);
         this.paramNameSeq = paramNameSeq;
@@ -72,6 +72,7 @@ public class QueryWrapper<T> extends AbstractWrapper<T, String, QueryWrapper<T>>
         this.expression = mergeSegments;
         this.lastSql = lastSql;
         this.sqlComment = sqlComment;
+        this.sqlFirst = sqlFirst;
     }
 
     @Override
@@ -99,7 +100,7 @@ public class QueryWrapper<T> extends AbstractWrapper<T, String, QueryWrapper<T>>
      */
     public LambdaQueryWrapper<T> lambda() {
         return new LambdaQueryWrapper<>(getEntity(), getEntityClass(), sqlSelect, paramNameSeq, paramNameValuePairs, expression,
-            lastSql, sqlComment);
+            lastSql, sqlComment, sqlFirst);
     }
 
     /**
@@ -111,6 +112,6 @@ public class QueryWrapper<T> extends AbstractWrapper<T, String, QueryWrapper<T>>
     @Override
     protected QueryWrapper<T> instance() {
         return new QueryWrapper<>(getEntity(), getEntityClass(), paramNameSeq, paramNameValuePairs, new MergeSegments(),
-            SharedString.emptyString(), SharedString.emptyString());
+            SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString());
     }
 }

+ 3 - 2
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/update/LambdaUpdateWrapper.java

@@ -74,7 +74,7 @@ public class LambdaUpdateWrapper<T> extends AbstractLambdaWrapper<T, LambdaUpdat
      */
     LambdaUpdateWrapper(T entity, List<String> sqlSet, AtomicInteger paramNameSeq,
                         Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments,
-                        SharedString lastSql, SharedString sqlComment) {
+                        SharedString lastSql, SharedString sqlComment, SharedString sqlFirst) {
         super.setEntity(entity);
         this.sqlSet = sqlSet;
         this.paramNameSeq = paramNameSeq;
@@ -82,6 +82,7 @@ public class LambdaUpdateWrapper<T> extends AbstractLambdaWrapper<T, LambdaUpdat
         this.expression = mergeSegments;
         this.lastSql = lastSql;
         this.sqlComment = sqlComment;
+        this.sqlFirst = sqlFirst;
     }
 
     @Override
@@ -111,6 +112,6 @@ public class LambdaUpdateWrapper<T> extends AbstractLambdaWrapper<T, LambdaUpdat
     @Override
     protected LambdaUpdateWrapper<T> instance() {
         return new LambdaUpdateWrapper<>(getEntity(), sqlSet, paramNameSeq, paramNameValuePairs, new MergeSegments(),
-            SharedString.emptyString(), SharedString.emptyString());
+            SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString());
     }
 }

+ 5 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/update/UpdateWrapper.java

@@ -55,7 +55,7 @@ public class UpdateWrapper<T> extends AbstractWrapper<T, String, UpdateWrapper<T
 
     private UpdateWrapper(T entity, List<String> sqlSet, AtomicInteger paramNameSeq,
                           Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments,
-                          SharedString lastSql, SharedString sqlComment) {
+                          SharedString lastSql, SharedString sqlComment, SharedString sqlFirst) {
         this.setEntity(entity);
         this.sqlSet = sqlSet;
         this.paramNameSeq = paramNameSeq;
@@ -63,6 +63,7 @@ public class UpdateWrapper<T> extends AbstractWrapper<T, String, UpdateWrapper<T
         this.expression = mergeSegments;
         this.lastSql = lastSql;
         this.sqlComment = sqlComment;
+        this.sqlFirst = sqlFirst;
     }
 
     @Override
@@ -93,12 +94,13 @@ public class UpdateWrapper<T> extends AbstractWrapper<T, String, UpdateWrapper<T
      * 返回一个支持 lambda 函数写法的 wrapper
      */
     public LambdaUpdateWrapper<T> lambda() {
-        return new LambdaUpdateWrapper<>(getEntity(), sqlSet, paramNameSeq, paramNameValuePairs, expression, lastSql, sqlComment);
+        return new LambdaUpdateWrapper<>(getEntity(), sqlSet, paramNameSeq, paramNameValuePairs, expression,
+            lastSql, sqlComment, sqlFirst);
     }
 
     @Override
     protected UpdateWrapper<T> instance() {
         return new UpdateWrapper<>(getEntity(), sqlSet, paramNameSeq, paramNameValuePairs, new MergeSegments(),
-            SharedString.emptyString(), SharedString.emptyString());
+            SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString());
     }
 }

+ 10 - 16
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/enums/SqlMethod.java

@@ -58,22 +58,16 @@ public enum SqlMethod {
     /**
      * 查询
      */
-    SELECT_BY_ID("selectById", "根据ID 查询一条数据", "SELECT %s FROM %s WHERE %s=#{%s}"),
-    SELECT_BY_MAP("selectByMap", "根据columnMap 查询一条数据", "<script>\nSELECT %s FROM %s %s\n</script>"),
-    SELECT_BATCH_BY_IDS("selectBatchIds", "根据ID集合,批量查询数据", "<script>\nSELECT %s FROM %s WHERE %s IN (%s)\n</script>"),
-    SELECT_ONE("selectOne", "查询满足条件一条数据", "<script>\nSELECT %s FROM %s %s %s\n</script>"),
-    SELECT_COUNT("selectCount", "查询满足条件总记录数", "<script>\nSELECT COUNT(%s) FROM %s %s %s\n</script>"),
-    SELECT_LIST("selectList", "查询满足条件所有数据", "<script>\nSELECT %s FROM %s %s %s\n</script>"),
-    SELECT_PAGE("selectPage", "查询满足条件所有数据(并翻页)", "<script>\nSELECT %s FROM %s %s %s\n</script>"),
-    SELECT_MAPS("selectMaps", "查询满足条件所有数据", "<script>\nSELECT %s FROM %s %s %s\n</script>"),
-    SELECT_MAPS_PAGE("selectMapsPage", "查询满足条件所有数据(并翻页)", "<script>\nSELECT %s FROM %s %s %s\n</script>"),
-    SELECT_OBJS("selectObjs", "查询满足条件所有数据", "<script>\nSELECT %s FROM %s %s %s\n</script>"),
-
-    /**
-     * 逻辑删除 -> 查询
-     */
-    LOGIC_SELECT_BY_ID("selectById", "根据ID 查询一条数据", "SELECT %s FROM %s WHERE %s=#{%s} %s"),
-    LOGIC_SELECT_BATCH_BY_IDS("selectBatchIds", "根据ID集合,批量查询数据", "<script>\nSELECT %s FROM %s WHERE %s IN (%s) %s\n</script>");
+    SELECT_BY_ID("selectById", "根据ID 查询一条数据", "SELECT %s FROM %s WHERE %s=#{%s} %s"),
+    SELECT_BY_MAP("selectByMap", "根据columnMap 查询一条数据", "<script>SELECT %s FROM %s %s\n</script>"),
+    SELECT_BATCH_BY_IDS("selectBatchIds", "根据ID集合,批量查询数据", "<script>SELECT %s FROM %s WHERE %s IN (%s) %s</script>"),
+    SELECT_ONE("selectOne", "查询满足条件一条数据", "<script>%s SELECT %s FROM %s %s %s\n</script>"),
+    SELECT_COUNT("selectCount", "查询满足条件总记录数", "<script>%s SELECT COUNT(%s) FROM %s %s %s\n</script>"),
+    SELECT_LIST("selectList", "查询满足条件所有数据", "<script>%s SELECT %s FROM %s %s %s\n</script>"),
+    SELECT_PAGE("selectPage", "查询满足条件所有数据(并翻页)", "<script>%s SELECT %s FROM %s %s %s\n</script>"),
+    SELECT_MAPS("selectMaps", "查询满足条件所有数据", "<script>%s SELECT %s FROM %s %s %s\n</script>"),
+    SELECT_MAPS_PAGE("selectMapsPage", "查询满足条件所有数据(并翻页)", "<script>\n %s SELECT %s FROM %s %s %s\n</script>"),
+    SELECT_OBJS("selectObjs", "查询满足条件所有数据", "<script>%s SELECT %s FROM %s %s %s\n</script>");
 
     private final String method;
     private final String desc;

+ 2 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/executor/MybatisCachingExecutor.java

@@ -138,12 +138,11 @@ public class MybatisCachingExecutor implements Executor {
                         return (List<E>) result;
                     }
                 } else {
-                    Long count;
                     if (page != null) {
                         if (page.isSearchCount()) {
                             CacheKey cacheKey = getCountCacheKey(ms, boundSql, parameterObject, RowBounds.DEFAULT);
-                            count = (Long) tcm.getObject(cache, cacheKey);
-                            return new PageList((List) result, count);
+                            Number count = (Number) tcm.getObject(cache, cacheKey);
+                            return new PageList((List) result, count.longValue());
                         }
                         return new PageList((List) result, 0L);
                     } else {

+ 19 - 6
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/AbstractMethod.java

@@ -19,7 +19,6 @@ import com.baomidou.mybatisplus.core.enums.SqlMethod;
 import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
 import com.baomidou.mybatisplus.core.metadata.TableInfo;
 import com.baomidou.mybatisplus.core.toolkit.Constants;
-import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
 import org.apache.ibatis.builder.MapperBuilderAssistant;
 import org.apache.ibatis.executor.keygen.KeyGenerator;
@@ -94,7 +93,8 @@ public abstract class AbstractMethod implements Constants {
      * @param prefix 前缀
      * @return sql
      */
-    protected String sqlSet(boolean logic, boolean ew, TableInfo table, boolean judgeAliasNull, String alias, String prefix) {
+    protected String sqlSet(boolean logic, boolean ew, TableInfo table, boolean judgeAliasNull, final String alias,
+                            final String prefix) {
         String sqlScript = table.getAllSqlSet(logic, prefix);
         if (judgeAliasNull) {
             sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", alias), true);
@@ -118,6 +118,16 @@ public abstract class AbstractMethod implements Constants {
             SqlScriptUtils.unSafeParam(Q_WRAPPER_SQL_COMMENT), EMPTY);
     }
 
+    /**
+     * SQL 注释
+     *
+     * @return sql
+     */
+    protected String sqlFirst() {
+        return SqlScriptUtils.convertChoose(String.format("%s != null and %s != null", WRAPPER, Q_WRAPPER_SQL_FIRST),
+            SqlScriptUtils.unSafeParam(Q_WRAPPER_SQL_FIRST), EMPTY);
+    }
+
     /**
      * SQL 查询所有表字段
      *
@@ -236,12 +246,15 @@ public abstract class AbstractMethod implements Constants {
         return infoStream.map(function).collect(joining(joiningVal));
     }
 
+    /**
+     * 获取乐观锁相关
+     *
+     * @param tableInfo 表信息
+     * @return String
+     */
     protected String optlockVersion(TableInfo tableInfo) {
         if (tableInfo.isWithVersion()) {
-            return "<if test=\"oli != null\">" +
-                " AND ${oli." + Constants.MP_OPTLOCK_VERSION_COLUMN +
-                "}=#{oli." + Constants.MP_OPTLOCK_VERSION_ORIGINAL + StringPool.RIGHT_BRACE +
-                "</if>";
+            return tableInfo.getVersionFieldInfo().getVersionOli(ENTITY, ENTITY_DOT);
         }
         return EMPTY;
     }

+ 1 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectBatchByIds.java

@@ -32,7 +32,7 @@ public class SelectBatchByIds extends AbstractMethod {
 
     @Override
     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
-        SqlMethod sqlMethod = SqlMethod.LOGIC_SELECT_BATCH_BY_IDS;
+        SqlMethod sqlMethod = SqlMethod.SELECT_BATCH_BY_IDS;
         SqlSource sqlSource = languageDriver.createSqlSource(configuration, String.format(sqlMethod.getSql(),
             sqlSelectColumns(tableInfo, false), tableInfo.getTableName(), tableInfo.getKeyColumn(),
             SqlScriptUtils.convertForeach("#{item}", COLLECTION, null, "item", COMMA),

+ 3 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectById.java

@@ -32,11 +32,11 @@ public class SelectById extends AbstractMethod {
 
     @Override
     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
-        SqlMethod sqlMethod = SqlMethod.LOGIC_SELECT_BY_ID;
+        SqlMethod sqlMethod = SqlMethod.SELECT_BY_ID;
         SqlSource sqlSource = new RawSqlSource(configuration, String.format(sqlMethod.getSql(),
             sqlSelectColumns(tableInfo, false),
             tableInfo.getTableName(), tableInfo.getKeyColumn(), tableInfo.getKeyProperty(),
-            tableInfo.getLogicDeleteSql(true, true)), Object.class);
-        return this.addSelectMappedStatementForTable(mapperClass, getMethod(sqlMethod), sqlSource, tableInfo);
+            tableInfo.getLogicDeleteSql(true, false)), Object.class);
+        return this.addSelectMappedStatementForTable(mapperClass, sqlMethod.getMethod(), sqlSource, tableInfo);
     }
 }

+ 10 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectCount.java

@@ -32,7 +32,16 @@ public class SelectCount extends AbstractMethod {
     @Override
     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
         SqlMethod sqlMethod = SqlMethod.SELECT_COUNT;
-        String sql = String.format(sqlMethod.getSql(), this.sqlCount(), tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo), sqlComment());
+        String sql = String.format(
+                sqlMethod.getSql(),
+                sqlFirst(),
+                this.sqlCount(),
+                tableInfo.getTableName(),
+                sqlWhereEntityWrapper(
+                        true,
+                        tableInfo
+                ),
+                sqlComment());
         SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
         return this.addSelectMappedStatementForOther(mapperClass, getMethod(sqlMethod), sqlSource, Integer.class);
     }

+ 7 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectList.java

@@ -32,9 +32,13 @@ public class SelectList extends AbstractMethod {
     @Override
     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
         SqlMethod sqlMethod = SqlMethod.SELECT_LIST;
-        String sql = String.format(sqlMethod.getSql(), sqlSelectColumns(tableInfo, true),
-            tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo),
-            sqlComment());
+        String sql = String.format(
+                sqlMethod.getSql(),
+                sqlFirst(),
+                sqlSelectColumns(tableInfo, true),
+                tableInfo.getTableName(),
+                sqlWhereEntityWrapper(true, tableInfo),
+                sqlComment());
         SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
         return this.addSelectMappedStatementForTable(mapperClass, getMethod(sqlMethod), sqlSource, tableInfo);
     }

+ 7 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectMaps.java

@@ -34,9 +34,13 @@ public class SelectMaps extends AbstractMethod {
     @Override
     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
         SqlMethod sqlMethod = SqlMethod.SELECT_MAPS;
-        String sql = String.format(sqlMethod.getSql(), sqlSelectColumns(tableInfo, true),
-            tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo),
-            sqlComment());
+        String sql = String.format(
+                sqlMethod.getSql(),
+                sqlFirst(),
+                sqlSelectColumns(tableInfo, true),
+                tableInfo.getTableName(),
+                sqlWhereEntityWrapper(true, tableInfo),
+                sqlComment());
         SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
         return this.addSelectMappedStatementForOther(mapperClass, getMethod(sqlMethod), sqlSource, Map.class);
     }

+ 7 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectMapsPage.java

@@ -34,9 +34,13 @@ public class SelectMapsPage extends AbstractMethod {
     @Override
     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
         SqlMethod sqlMethod = SqlMethod.SELECT_MAPS_PAGE;
-        String sql = String.format(sqlMethod.getSql(), sqlSelectColumns(tableInfo, true),
-            tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo),
-            sqlComment());
+        String sql = String.format(
+                sqlMethod.getSql(),
+                sqlFirst(),
+                sqlSelectColumns(tableInfo, true),
+                tableInfo.getTableName(),
+                sqlWhereEntityWrapper(true, tableInfo),
+                sqlComment());
         SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
         return this.addSelectMappedStatementForOther(mapperClass, getMethod(sqlMethod), sqlSource, Map.class);
     }

+ 7 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectObjs.java

@@ -32,9 +32,13 @@ public class SelectObjs extends AbstractMethod {
     @Override
     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
         SqlMethod sqlMethod = SqlMethod.SELECT_OBJS;
-        String sql = String.format(sqlMethod.getSql(), sqlSelectObjsColumns(tableInfo),
-            tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo),
-            sqlComment());
+        String sql = String.format(
+                sqlMethod.getSql(),
+                sqlFirst(),
+                sqlSelectObjsColumns(tableInfo),
+                tableInfo.getTableName(),
+                sqlWhereEntityWrapper(true, tableInfo),
+                sqlComment());
         SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
         return this.addSelectMappedStatementForOther(mapperClass, getMethod(sqlMethod), sqlSource, Object.class);
     }

+ 8 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectOne.java

@@ -32,9 +32,14 @@ public class SelectOne extends AbstractMethod {
     @Override
     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
         SqlMethod sqlMethod = SqlMethod.SELECT_ONE;
-        SqlSource sqlSource = languageDriver.createSqlSource(configuration, String.format(sqlMethod.getSql(),
-            this.sqlSelectColumns(tableInfo, true), tableInfo.getTableName(),
-            this.sqlWhereEntityWrapper(true, tableInfo), sqlComment()),
+        SqlSource sqlSource = languageDriver.createSqlSource(configuration,
+                String.format(
+                        sqlMethod.getSql(),
+                        sqlFirst(),
+                        this.sqlSelectColumns(tableInfo, true),
+                        tableInfo.getTableName(),
+                        this.sqlWhereEntityWrapper(true, tableInfo),
+                        sqlComment()),
             modelClass);
         return this.addSelectMappedStatementForTable(mapperClass, getMethod(sqlMethod), sqlSource, tableInfo);
     }

+ 7 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectPage.java

@@ -32,9 +32,13 @@ public class SelectPage extends AbstractMethod {
     @Override
     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
         SqlMethod sqlMethod = SqlMethod.SELECT_PAGE;
-        String sql = String.format(sqlMethod.getSql(), sqlSelectColumns(tableInfo, true),
-            tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo),
-            sqlComment());
+        String sql = String.format(
+                sqlMethod.getSql(),
+                sqlFirst(),
+                sqlSelectColumns(tableInfo, true),
+                tableInfo.getTableName(),
+                sqlWhereEntityWrapper(true, tableInfo),
+                sqlComment());
         SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
         return this.addSelectMappedStatementForTable(mapperClass, getMethod(sqlMethod), sqlSource, tableInfo);
     }

+ 10 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableFieldInfo.java

@@ -462,6 +462,16 @@ public class TableFieldInfo implements Constants {
         return builder.build();
     }
 
+    public String getVersionOli(final String alias, final String prefix) {
+        final String oli = " AND " + column + EQUALS + SqlScriptUtils.safeParam(MP_OPTLOCK_VERSION_ORIGINAL);
+        final String ognlStr = convertIfProperty(prefix, property);
+        if (isCharSequence) {
+            return SqlScriptUtils.convertIf(oli, String.format("%s != null and %s != null and %s != ''", alias, ognlStr, ognlStr), false);
+        } else {
+            return SqlScriptUtils.convertIf(oli, String.format("%s != null and %s != null", alias, ognlStr), false);
+        }
+    }
+
     /**
      * 转换成 if 标签的脚本片段
      *

+ 13 - 6
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableInfoHelper.java

@@ -26,6 +26,8 @@ import org.apache.ibatis.executor.keygen.SelectKeyGenerator;
 import org.apache.ibatis.logging.Log;
 import org.apache.ibatis.logging.LogFactory;
 import org.apache.ibatis.mapping.*;
+import org.apache.ibatis.reflection.Reflector;
+import org.apache.ibatis.reflection.ReflectorFactory;
 import org.apache.ibatis.scripting.LanguageDriver;
 import org.apache.ibatis.session.Configuration;
 
@@ -238,6 +240,9 @@ public class TableInfoHelper {
     public static void initTableFields(Class<?> clazz, GlobalConfig globalConfig, TableInfo tableInfo) {
         /* 数据库全局配置 */
         GlobalConfig.DbConfig dbConfig = globalConfig.getDbConfig();
+        ReflectorFactory reflectorFactory = tableInfo.getConfiguration().getReflectorFactory();
+        //TODO @咩咩 有空一起来撸完这反射模块.
+        Reflector reflector = reflectorFactory.findForClass(clazz);
         List<Field> list = getAllFields(clazz);
         // 标记是否读取到主键
         boolean isReadPK = false;
@@ -251,9 +256,9 @@ public class TableInfoHelper {
              */
             if (!isReadPK) {
                 if (existTableId) {
-                    isReadPK = initTableIdWithAnnotation(dbConfig, tableInfo, field, clazz);
+                    isReadPK = initTableIdWithAnnotation(dbConfig, tableInfo, field, clazz, reflector);
                 } else {
-                    isReadPK = initTableIdWithoutAnnotation(dbConfig, tableInfo, field, clazz);
+                    isReadPK = initTableIdWithoutAnnotation(dbConfig, tableInfo, field, clazz, reflector);
                 }
                 if (isReadPK) {
                     continue;
@@ -302,10 +307,11 @@ public class TableInfoHelper {
      * @param tableInfo 表信息
      * @param field     字段
      * @param clazz     实体类
+     * @param reflector Reflector
      * @return true 继续下一个属性判断,返回 continue;
      */
     private static boolean initTableIdWithAnnotation(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo,
-                                                     Field field, Class<?> clazz) {
+                                                     Field field, Class<?> clazz, Reflector reflector) {
         TableId tableId = field.getAnnotation(TableId.class);
         boolean underCamel = tableInfo.isUnderCamel();
         if (tableId != null) {
@@ -335,7 +341,7 @@ public class TableInfoHelper {
                 tableInfo.setKeyRelated(checkRelated(underCamel, field.getName(), column))
                     .setKeyColumn(column)
                     .setKeyProperty(field.getName())
-                    .setKeyType(field.getType());
+                    .setKeyType(reflector.getGetterType(field.getName()));
                 return true;
             } else {
                 throwExceptionId(clazz);
@@ -352,10 +358,11 @@ public class TableInfoHelper {
      * @param tableInfo 表信息
      * @param field     字段
      * @param clazz     实体类
+     * @param reflector Reflector
      * @return true 继续下一个属性判断,返回 continue;
      */
     private static boolean initTableIdWithoutAnnotation(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo,
-                                                        Field field, Class<?> clazz) {
+                                                        Field field, Class<?> clazz, Reflector reflector) {
         String column = field.getName();
         if (dbConfig.isCapitalMode()) {
             column = column.toUpperCase();
@@ -366,7 +373,7 @@ public class TableInfoHelper {
                     .setIdType(dbConfig.getIdType())
                     .setKeyColumn(column)
                     .setKeyProperty(field.getName())
-                    .setKeyType(field.getType());
+                    .setKeyType(reflector.getGetterType(field.getName()));
                 return true;
             } else {
                 throwExceptionId(clazz);

+ 4 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/Constants.java

@@ -92,6 +92,10 @@ public interface Constants extends StringPool {
      * wrapper 类的属性 sqlComment
      */
     String Q_WRAPPER_SQL_COMMENT = WRAPPER_DOT + "sqlComment";
+    /**
+     * wrapper 类的属性 sqlFirst
+     */
+    String Q_WRAPPER_SQL_FIRST = WRAPPER_DOT + "sqlFirst";
     /**
      * columnMap
      */

+ 10 - 10
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/MybatisDefaultParameterHandlerTest.java

@@ -101,16 +101,16 @@ class MybatisDefaultParameterHandlerTest {
         Assertions.assertNotNull(model2.getId());
         Assertions.assertNotNull(model2.getInsertOperator());
         Assertions.assertNull(model2.getUpdateOperator());
-        //map参数
-        Model model3 = new Model("坦克");
-        Map<String, Object> params2 = new HashMap<>();
-        params2.put(Constants.ENTITY, new HashMap<String, Object>() {{
-            put(Constants.MP_OPTLOCK_ET_ORIGINAL, model3);
-        }});
-        MybatisDefaultParameterHandler.processParameter(mappedStatement, params2);
-        Assertions.assertNotNull(model3.getId());
-        Assertions.assertNotNull(model3.getInsertOperator());
-        Assertions.assertNull(model3.getUpdateOperator());
+//        //map参数
+//        Model model3 = new Model("坦克");
+//        Map<String, Object> params2 = new HashMap<>();
+//        params2.put(Constants.ENTITY, new HashMap<String, Object>() {{
+//            put(Constants.MP_OPTLOCK_ET_ORIGINAL, model3);
+//        }});
+//        MybatisDefaultParameterHandler.processParameter(mappedStatement, params2);
+//        Assertions.assertNotNull(model3.getId());
+//        Assertions.assertNotNull(model3.getInsertOperator());
+//        Assertions.assertNull(model3.getUpdateOperator());
         //普通更新
         Model model4 = new Model(1L,"坦克");
         mappedStatement = new MappedStatement.Builder(configuration, "***", staticSqlSource, SqlCommandType.UPDATE).build();

+ 3 - 1
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/test/EncryptTest.java

@@ -19,10 +19,12 @@ import com.baomidou.mybatisplus.annotation.FieldFill;
 import com.baomidou.mybatisplus.annotation.FieldStrategy;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.core.MybatisConfiguration;
 import com.baomidou.mybatisplus.core.metadata.TableInfo;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
 import com.baomidou.mybatisplus.core.toolkit.EncryptUtils;
 import lombok.Data;
+import org.apache.ibatis.builder.MapperBuilderAssistant;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -46,7 +48,7 @@ class EncryptTest {
 
     @Test
     void testTableInfoHelper() {
-        TableInfo info = TableInfoHelper.initTableInfo(null, Xx.class);
+        TableInfo info = TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), Xx.class);
         System.out.println("----------- AllInsertSqlColumn -----------");
         System.out.println(info.getAllInsertSqlColumnMaybeIf());
         System.out.println("----------- AllInsertSqlProperty -----------");

+ 3 - 1
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/test/WrapperTest.java

@@ -15,12 +15,14 @@
  */
 package com.baomidou.mybatisplus.core.test;
 
+import com.baomidou.mybatisplus.core.MybatisConfiguration;
 import com.baomidou.mybatisplus.core.conditions.ISqlSegment;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
 import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import org.apache.ibatis.builder.MapperBuilderAssistant;
 import org.junit.jupiter.api.Test;
 
 import java.time.LocalDate;
@@ -187,7 +189,7 @@ class WrapperTest {
 
     @Test
     void testPluralLambda() {
-        TableInfoHelper.initTableInfo(null, User.class);
+        TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), User.class);
         QueryWrapper<User> queryWrapper = new QueryWrapper<>();
         queryWrapper.lambda().eq(User::getName, "sss");
         queryWrapper.lambda().eq(User::getName, "sss2");

+ 12 - 0
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/conditions/AbstractChainWrapper.java

@@ -211,6 +211,12 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
         return typedThis;
     }
 
+    @Override
+    public Children func(Consumer<Children> consumer) {
+        getWrapper().func(consumer);
+        return typedThis;
+    }
+
     @Override
     public Children or(boolean condition) {
         getWrapper().or(condition);
@@ -235,6 +241,12 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
         return typedThis;
     }
 
+    @Override
+    public Children first(boolean condition, String firstSql) {
+        getWrapper().first(condition, firstSql);
+        return typedThis;
+    }
+
     @Override
     public Children exists(boolean condition, String existsSql) {
         getWrapper().exists(condition, existsSql);

+ 0 - 1
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/injector/methods/Upsert.java

@@ -32,7 +32,6 @@ import org.apache.ibatis.mapping.SqlSource;
  * @author fly
  * @since 2018-04-06
  */
-@SuppressWarnings("all")
 public class Upsert extends AbstractMethod {
 
     @Override

+ 2 - 2
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/IllegalSQLInterceptor.java

@@ -267,8 +267,8 @@ public class IllegalSQLInterceptor implements Interceptor {
             ResultSet rs;
             try {
                 DatabaseMetaData metadata = conn.getMetaData();
-                String catalog = StringUtils.isEmpty(dbName)? conn.getCatalog():dbName;
-                String schema = StringUtils.isEmpty(dbName)? conn.getSchema():dbName;
+                String catalog = StringUtils.isBlank(dbName) ? conn.getCatalog() : dbName;
+                String schema = StringUtils.isBlank(dbName) ? conn.getSchema() : dbName;
                 rs = metadata.getIndexInfo(catalog, schema, tableName, false, true);
                 indexInfos = new ArrayList<>();
                 while (rs.next()) {

+ 3 - 7
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/OptimisticLockerInterceptor.java

@@ -32,7 +32,6 @@ import java.lang.reflect.Field;
 import java.sql.Timestamp;
 import java.time.LocalDateTime;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
 
@@ -73,7 +72,7 @@ public class OptimisticLockerInterceptor implements Interceptor {
         if (param instanceof Map) {
             Map map = (Map) param;
             //updateById(et), update(et, wrapper);
-            Object et = map.get(Constants.ENTITY);
+            Object et = map.getOrDefault(Constants.ENTITY, null);
             if (et != null) {
                 // entity
                 String methodId = ms.getId();
@@ -93,7 +92,7 @@ public class OptimisticLockerInterceptor implements Interceptor {
                 // 新的 version 值
                 Object updatedVersionVal = this.getUpdatedVersionVal(fieldInfo.getPropertyType(), originalVersionVal);
                 if (PARAM_UPDATE_METHOD_NAME.equals(methodName)) {
-                    AbstractWrapper<?, ?, ?> aw = (AbstractWrapper<?, ?, ?>) map.get(Constants.WRAPPER);
+                    AbstractWrapper<?, ?, ?> aw = (AbstractWrapper<?, ?, ?>) map.getOrDefault(Constants.WRAPPER, null);
                     if (aw == null) {
                         UpdateWrapper<?> uw = new UpdateWrapper<>();
                         uw.eq(versionColumn, originalVersionVal);
@@ -102,10 +101,7 @@ public class OptimisticLockerInterceptor implements Interceptor {
                         aw.apply(versionColumn + " = {0}", originalVersionVal);
                     }
                 } else {
-                    Map<String, Object> entityMap = new HashMap<>(3);
-                    entityMap.put(Constants.MP_OPTLOCK_VERSION_COLUMN, versionColumn);
-                    entityMap.put(Constants.MP_OPTLOCK_VERSION_ORIGINAL, originalVersionVal);
-                    map.put(Constants.MP_OPTLOCK_INTERCEPTOR, entityMap);
+                    map.put(Constants.MP_OPTLOCK_VERSION_ORIGINAL, originalVersionVal);
                 }
                 versionField.set(et, updatedVersionVal);
                 return invocation.proceed();

+ 3 - 2
mybatis-plus-extension/src/main/kotlin/com/baomidou/mybatisplus/extension/kotlin/KtQueryWrapper.kt

@@ -50,7 +50,7 @@ class KtQueryWrapper<T : Any> : AbstractKtWrapper<T, KtQueryWrapper<T>>, Query<K
 
     internal constructor(entity: T, entityClass: Class<T>, sqlSelect: SharedString, paramNameSeq: AtomicInteger,
                          paramNameValuePairs: Map<String, Any>, mergeSegments: MergeSegments,
-                         lastSql: SharedString, sqlComment: SharedString) {
+                         lastSql: SharedString, sqlComment: SharedString, sqlFirst: SharedString) {
         this.entity = entity
         this.paramNameSeq = paramNameSeq
         this.paramNameValuePairs = paramNameValuePairs
@@ -59,6 +59,7 @@ class KtQueryWrapper<T : Any> : AbstractKtWrapper<T, KtQueryWrapper<T>>, Query<K
         this.entityClass = entityClass
         this.lastSql = lastSql
         this.sqlComment = sqlComment
+        this.sqlFirst = sqlFirst
     }
 
     /**
@@ -108,6 +109,6 @@ class KtQueryWrapper<T : Any> : AbstractKtWrapper<T, KtQueryWrapper<T>>, Query<K
      */
     override fun instance(): KtQueryWrapper<T> {
         return KtQueryWrapper(entity, entityClass, sqlSelect, paramNameSeq, paramNameValuePairs, expression,
-            SharedString.emptyString(), SharedString.emptyString())
+            SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString())
     }
 }

+ 4 - 3
mybatis-plus-extension/src/main/kotlin/com/baomidou/mybatisplus/extension/kotlin/KtUpdateWrapper.kt

@@ -48,14 +48,15 @@ class KtUpdateWrapper<T : Any> : AbstractKtWrapper<T, KtUpdateWrapper<T>>, Updat
         this.initNeed()
     }
 
-    internal constructor(entity: T, paramNameSeq: AtomicInteger, paramNameValuePairs: Map<String, Any>,
-                         mergeSegments: MergeSegments, lastSql: SharedString, sqlComment: SharedString) {
+    internal constructor(entity: T, paramNameSeq: AtomicInteger, paramNameValuePairs: Map<String, Any>, mergeSegments: MergeSegments,
+                         lastSql: SharedString, sqlComment: SharedString, sqlFirst: SharedString) {
         this.entity = entity
         this.paramNameSeq = paramNameSeq
         this.paramNameValuePairs = paramNameValuePairs
         this.expression = mergeSegments
         this.lastSql = lastSql
         this.sqlComment = sqlComment
+        this.sqlFirst = sqlFirst
     }
 
     override fun getSqlSet(): String? {
@@ -79,6 +80,6 @@ class KtUpdateWrapper<T : Any> : AbstractKtWrapper<T, KtUpdateWrapper<T>>, Updat
 
     override fun instance(): KtUpdateWrapper<T> {
         return KtUpdateWrapper(entity, paramNameSeq, paramNameValuePairs, expression, SharedString.emptyString(),
-            SharedString.emptyString())
+            SharedString.emptyString(), SharedString.emptyString())
     }
 }

+ 8 - 8
mybatis-plus-extension/src/test/java/com/baomidou/mybatisplus/extension/plugins/pagination/SelectBodyToPlainSelectTest.java

@@ -62,34 +62,34 @@ class SelectBodyToPlainSelectTest {
         String actualSql = PaginationInterceptor
             .concatOrderBy("select * from test", page);
 
-        assertThat(actualSql).isEqualTo("SELECT * FROM test ORDER BY column");
+        assertThat(actualSql).isEqualTo("SELECT * FROM test ORDER BY column ASC");
 
         String actualSqlWhere = PaginationInterceptor
             .concatOrderBy("select * from test where 1 = 1", page);
 
-        assertThat(actualSqlWhere).isEqualTo("SELECT * FROM test WHERE 1 = 1 ORDER BY column");
+        assertThat(actualSqlWhere).isEqualTo("SELECT * FROM test WHERE 1 = 1 ORDER BY column ASC");
     }
 
     @Test
     void testPaginationInterceptorConcatOrderByFix() {
         String actualSql = PaginationInterceptor
             .concatOrderBy("select * from test union select * from test2", page);
-        assertThat(actualSql).isEqualTo("SELECT * FROM test UNION SELECT * FROM test2 ORDER BY column");
+        assertThat(actualSql).isEqualTo("SELECT * FROM test UNION SELECT * FROM test2 ORDER BY column ASC");
 
         String actualSqlUnionAll = PaginationInterceptor
             .concatOrderBy("select * from test union all select * from test2", page);
-        assertThat(actualSqlUnionAll).isEqualTo("SELECT * FROM test UNION ALL SELECT * FROM test2 ORDER BY column");
+        assertThat(actualSqlUnionAll).isEqualTo("SELECT * FROM test UNION ALL SELECT * FROM test2 ORDER BY column ASC");
     }
 
     @Test
     void testPaginationInterceptorConcatOrderByFixWithWhere() {
         String actualSqlWhere = PaginationInterceptor
             .concatOrderBy("select * from test where 1 = 1 union select * from test2 where 1 = 1", page);
-        assertThat(actualSqlWhere).isEqualTo("SELECT * FROM test WHERE 1 = 1 UNION SELECT * FROM test2 WHERE 1 = 1 ORDER BY column");
+        assertThat(actualSqlWhere).isEqualTo("SELECT * FROM test WHERE 1 = 1 UNION SELECT * FROM test2 WHERE 1 = 1 ORDER BY column ASC");
 
         String actualSqlUnionAll = PaginationInterceptor
             .concatOrderBy("select * from test where 1 = 1 union all select * from test2 where 1 = 1 ", page);
-        assertThat(actualSqlUnionAll).isEqualTo("SELECT * FROM test WHERE 1 = 1 UNION ALL SELECT * FROM test2 WHERE 1 = 1 ORDER BY column");
+        assertThat(actualSqlUnionAll).isEqualTo("SELECT * FROM test WHERE 1 = 1 UNION ALL SELECT * FROM test2 WHERE 1 = 1 ORDER BY column ASC");
     }
 
     @Test
@@ -97,12 +97,12 @@ class SelectBodyToPlainSelectTest {
         String actualSql = PaginationInterceptor
             .concatOrderBy("select * from test", page);
 
-        assertThat(actualSql).isEqualTo("SELECT * FROM test ORDER BY column");
+        assertThat(actualSql).isEqualTo("SELECT * FROM test ORDER BY column ASC");
 
         String actualSqlWhere = PaginationInterceptor
             .concatOrderBy("select * from test where 1 = 1", page);
 
-        assertThat(actualSqlWhere).isEqualTo("SELECT * FROM test WHERE 1 = 1 ORDER BY column");
+        assertThat(actualSqlWhere).isEqualTo("SELECT * FROM test WHERE 1 = 1 ORDER BY column ASC");
     }
 
 }

+ 3 - 1
mybatis-plus-extension/src/test/kotlin/com/baomidou/mybatisplus/extension/kotlin/WrapperTest.kt

@@ -15,8 +15,10 @@
  */
 package com.baomidou.mybatisplus.extension.kotlin
 
+import com.baomidou.mybatisplus.core.MybatisConfiguration
 import com.baomidou.mybatisplus.core.conditions.ISqlSegment
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper
+import org.apache.ibatis.builder.MapperBuilderAssistant
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 
@@ -24,7 +26,7 @@ class WrapperTest {
 
     @BeforeEach
     fun beforeInit() {
-        TableInfoHelper.initTableInfo(null, User::class.java)
+        TableInfoHelper.initTableInfo(MapperBuilderAssistant(MybatisConfiguration(), ""), User::class.java)
     }
 
     private fun logSqlSegment(explain: String, sqlSegment: ISqlSegment) {

+ 8 - 7
mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/config/StrategyConfig.java

@@ -164,14 +164,13 @@ public class StrategyConfig {
      */
     private List<TableFill> tableFillList = null;
     /**
-     * 启用like匹配支持
-     * 目前所知微软系需要关闭,其他数据库等待反馈,
-     * sql可能要改动一下才能支持,没数据库环境搞,请手动关闭使用内存过滤的方式。
-     * 数据库语法不能支持使用like过滤表的话,可以考虑关闭此开关.
+     * 启用sql过滤
+     * 语法不能支持使用sql过滤表的话,可以考虑关闭此开关.
+     * 目前所知微软系需要关闭,其他数据库等待反馈,sql可能要改动一下才能支持,没数据库环境搞,请手动关闭使用内存过滤的方式。
      *
      * @since 3.3.1
      */
-    private boolean enableLike = true;
+    private boolean enableSqlFilter = true;
     /**
      * 包含表名
      *
@@ -291,12 +290,14 @@ public class StrategyConfig {
         return this;
     }
 
-    public void setSuperControllerClass(Class<?> clazz) {
+    public StrategyConfig setSuperControllerClass(Class<?> clazz) {
         this.superControllerClass = clazz.getName();
+        return this;
     }
 
-    public void setSuperControllerClass(String superControllerClass) {
+    public StrategyConfig setSuperControllerClass(String superControllerClass) {
         this.superControllerClass = superControllerClass;
+        return this;
     }
 
     /**

+ 9 - 9
mybatis-plus-generator/src/main/java/com/baomidou/mybatisplus/generator/config/builder/ConfigBuilder.java

@@ -460,19 +460,19 @@ public class ConfigBuilder {
                 tablesSql = String.format(tablesSql, schema);
             }
             StringBuilder sql = new StringBuilder(tablesSql);
-            if (config.isEnableLike()) {
+            if (config.isEnableSqlFilter()) {
                 if (config.getLikeTable() != null) {
                     sql.append(" AND ").append(dbQuery.tableName()).append(" LIKE '").append(config.getLikeTable().getValue()).append("'");
                 } else if (config.getNotLikeTable() != null) {
                     sql.append(" AND ").append(dbQuery.tableName()).append(" NOT LIKE '").append(config.getNotLikeTable().getValue()).append("'");
                 }
-            }
-            if (isInclude) {
-                sql.append(" AND ").append(dbQuery.tableName()).append(" IN (")
-                    .append(Arrays.stream(config.getInclude()).map(tb -> "'" + tb + "'").collect(Collectors.joining(","))).append(")");
-            } else if (isExclude) {
-                sql.append(" AND ").append(dbQuery.tableName()).append(" NOT IN (")
-                    .append(Arrays.stream(config.getExclude()).map(tb -> "'" + tb + "'").collect(Collectors.joining(","))).append(")");
+                if (isInclude) {
+                    sql.append(" AND ").append(dbQuery.tableName()).append(" IN (")
+                        .append(Arrays.stream(config.getInclude()).map(tb -> "'" + tb + "'").collect(Collectors.joining(","))).append(")");
+                } else if (isExclude) {
+                    sql.append(" AND ").append(dbQuery.tableName()).append(" NOT IN (")
+                        .append(Arrays.stream(config.getExclude()).map(tb -> "'" + tb + "'").collect(Collectors.joining(","))).append(")");
+                }
             }
             TableInfo tableInfo;
             try (PreparedStatement preparedStatement = connection.prepareStatement(sql.toString());
@@ -594,7 +594,7 @@ public class ConfigBuilder {
                      ResultSet pkResults = pkQueryStmt.executeQuery()) {
                     while (pkResults.next()) {
                         String primaryKey = pkResults.getString(dbQuery.fieldKey());
-                        if (Boolean.valueOf(primaryKey)) {
+                        if (Boolean.parseBoolean(primaryKey)) {
                             h2PkColumns.add(pkResults.getString(dbQuery.fieldName()));
                         }
                     }

+ 4 - 2
mybatis-plus-generator/src/test/java/com/baomidou/mybatisplus/test/generator/H2CodeGeneratorTest.java

@@ -18,6 +18,8 @@ import org.junit.jupiter.api.Test;
  */
 class H2CodeGeneratorTest {
 
+    private static String outPutDir = System.getProperty("os.name").toLowerCase().contains("windows") ? "D://tmp" : "tmp";
+
     private DataSourceConfig dataSourceConfig() {
         String dbUrl = "jdbc:h2:mem:test;MODE=mysql;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE";
         DataSourceConfig dataSourceConfig = new DataSourceConfig();
@@ -34,7 +36,7 @@ class H2CodeGeneratorTest {
         strategyConfig
             .setCapitalMode(true)
             .setEntityLombokModel(false)
-            .setEnableLike(false)
+            .setEnableSqlFilter(true)
             .setNaming(NamingStrategy.underline_to_camel);
         return strategyConfig;
     }
@@ -44,7 +46,7 @@ class H2CodeGeneratorTest {
         globalConfig.setActiveRecord(false)
             .setIdType(IdType.ASSIGN_ID)
             .setAuthor("test")
-            .setOutputDir("/tmp/")
+            .setOutputDir(outPutDir)
             .setOpen(true)
             .setFileOverride(true);
         return globalConfig;

+ 3 - 1
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/SampleTest.java

@@ -15,12 +15,14 @@
  */
 package com.baomidou.mybatisplus.test;
 
+import com.baomidou.mybatisplus.core.MybatisConfiguration;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.TableInfo;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.test.mysql.entity.CommonData;
 import com.baomidou.mybatisplus.test.mysql.entity.CommonLogicData;
+import org.apache.ibatis.builder.MapperBuilderAssistant;
 import org.apache.ibatis.reflection.DefaultReflectorFactory;
 import org.apache.ibatis.reflection.MetaClass;
 import org.junit.jupiter.api.Test;
@@ -29,7 +31,7 @@ class SampleTest {
 
     @Test
     void testTableInfoHelper2() {
-        TableInfo info = TableInfoHelper.initTableInfo(null, CommonLogicData.class);
+        TableInfo info = TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), CommonLogicData.class);
 //        System.out.println("----------- AllInsertSqlColumn -----------");
 //        System.out.println(info.getAllInsertSqlColumn());
 //        System.out.println("----------- AllInsertSqlProperty -----------");

+ 0 - 1
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/config/MybatisPlusConfig.java

@@ -35,7 +35,6 @@ import net.sf.jsqlparser.statement.delete.Delete;
 import net.sf.jsqlparser.statement.insert.Insert;
 import net.sf.jsqlparser.statement.select.SelectBody;
 import net.sf.jsqlparser.statement.update.Update;
-import org.apache.ibatis.plugin.Interceptor;
 import org.apache.ibatis.session.ExecutorType;
 import org.apache.ibatis.session.SqlSessionFactory;
 import org.apache.ibatis.type.EnumOrdinalTypeHandler;

+ 39 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/GenericIdTest.java

@@ -0,0 +1,39 @@
+package com.baomidou.mybatisplus.test.h2.issues.genericid;
+
+import com.baomidou.mybatisplus.test.h2.issues.genericid.entity.LongEntity;
+import com.baomidou.mybatisplus.test.h2.issues.genericid.entity.StringEntity;
+import com.baomidou.mybatisplus.test.h2.issues.genericid.mapper.LongEntityMapper;
+import com.baomidou.mybatisplus.test.h2.issues.genericid.mapper.StringEntityMapper;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+/**
+ * 泛型主键问题
+ * https://gitee.com/baomidou/mybatis-plus/issues/I171CQ
+ *
+ * @author nieqiuqiu
+ * @date 2019-12-20
+ */
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+@ExtendWith(SpringExtension.class)
+@ContextConfiguration(locations = {"classpath:issues/genericid/spring.xml"})
+class GenericIdTest {
+
+    @Autowired
+    private LongEntityMapper longEntityMapper;
+
+    @Autowired
+    private StringEntityMapper stringEntityMapper;
+
+    @Test
+    void test() {
+        longEntityMapper.insert(new LongEntity("testLong"));
+        stringEntityMapper.insert(new StringEntity("testString"));
+    }
+
+}

+ 41 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/MybatisPlusConfig.java

@@ -0,0 +1,41 @@
+package com.baomidou.mybatisplus.test.h2.issues.genericid;
+
+import com.baomidou.mybatisplus.core.MybatisConfiguration;
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
+import org.apache.ibatis.session.ExecutorType;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.type.EnumOrdinalTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.sql.DataSource;
+
+/**
+ * config
+ *
+ * @author nieqiuqiu
+ * @date 2019-12-20
+ */
+@Configuration
+@MapperScan("com.baomidou.mybatisplus.test.h2.issues.genericid.mapper")
+public class MybatisPlusConfig {
+
+    @Bean
+    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
+        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
+        sqlSessionFactory.setDataSource(dataSource);
+        MybatisConfiguration configuration = new MybatisConfiguration();
+        configuration.setJdbcTypeForNull(JdbcType.NULL);
+        configuration.setMapUnderscoreToCamelCase(true);
+        configuration.setDefaultExecutorType(ExecutorType.REUSE);
+        configuration.setDefaultEnumTypeHandler(EnumOrdinalTypeHandler.class);
+        sqlSessionFactory.setConfiguration(configuration);
+        PaginationInterceptor pagination = new PaginationInterceptor();
+        sqlSessionFactory.setPlugins(pagination);
+        return sqlSessionFactory.getObject();
+    }
+
+}

+ 18 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/entity/LongEntity.java

@@ -0,0 +1,18 @@
+package com.baomidou.mybatisplus.test.h2.issues.genericid.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName("t_i171cq_long")
+@EqualsAndHashCode(callSuper = true)
+public class LongEntity extends SuperEntity<Long> {
+
+    private String name;
+
+}

+ 18 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/entity/StringEntity.java

@@ -0,0 +1,18 @@
+package com.baomidou.mybatisplus.test.h2.issues.genericid.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName("t_i171cq_string")
+@EqualsAndHashCode(callSuper = true)
+public class StringEntity extends SuperEntity<String> {
+
+    private String name;
+
+}

+ 15 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/entity/SuperEntity.java

@@ -0,0 +1,15 @@
+package com.baomidou.mybatisplus.test.h2.issues.genericid.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+class SuperEntity<ID extends Serializable> {
+
+    @TableId(type = IdType.ASSIGN_ID)
+    private ID id;
+
+}

+ 14 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/mapper/LongEntityMapper.java

@@ -0,0 +1,14 @@
+package com.baomidou.mybatisplus.test.h2.issues.genericid.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.test.h2.issues.genericid.entity.LongEntity;
+
+/**
+ * long mapper
+ *
+ * @author nieqiuqiu
+ * @date 2019-12-20
+ */
+public interface LongEntityMapper extends BaseMapper<LongEntity> {
+
+}

+ 14 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/issues/genericid/mapper/StringEntityMapper.java

@@ -0,0 +1,14 @@
+package com.baomidou.mybatisplus.test.h2.issues.genericid.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.test.h2.issues.genericid.entity.StringEntity;
+
+/**
+ * string mapper
+ *
+ * @author nieqiuqiu
+ * @date 2019-12-20
+ */
+public interface StringEntityMapper extends BaseMapper<StringEntity> {
+
+}

+ 2 - 2
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/tenant/TenantTest.java

@@ -24,7 +24,7 @@ class TenantTest {
     @Autowired
     private StudentMapper studentMapper;
 
-    @Test
+//    @Test
     void testSimple(){
         TenantConfig.TENANT_ID = 2L;
         Student student1 = studentMapper.selectById(1L);
@@ -38,7 +38,7 @@ class TenantTest {
         Assertions.assertNotNull(student2);
     }
 
-    @Test
+//    @Test
     void testPage(){
         TenantConfig.TENANT_ID = 2L;
         Page<Student> page1 = studentMapper.selectPage(new Page<>(0, 10), new QueryWrapper<>());

+ 4 - 1
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/mysql/SelectCountDistinctTest.java

@@ -48,7 +48,10 @@ class SelectCountDistinctTest {
     void testCountDistinct() {
         QueryWrapper<CommonData> distinct = new QueryWrapper<>();
         distinct.select("distinct test_int");
-        distinct.eq("test_int", 25).or().eq("test_str", "test");
+        distinct.eq("test_int", 25)
+                .or()
+                .eq("test_str", "test")
+                .first("/*Force Master*/");
         int count = commonDataMapper.selectCount(distinct);
         Assertions.assertEquals(1, count);
     }

+ 14 - 0
mybatis-plus/src/test/resources/issues/genericid/spring.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns="http://www.springframework.org/schema/beans"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
+
+    <context:component-scan base-package="com.baomidou.mybatisplus.test.h2.issues.genericid"/>
+
+    <bean class="com.baomidou.mybatisplus.test.h2.config.DBConfig">
+        <property name="locationPattern" value="classpath:/issues/genericid/sql/*.sql"/>
+    </bean>
+
+</beans>

+ 12 - 0
mybatis-plus/src/test/resources/issues/genericid/sql/init.ddl.sql

@@ -0,0 +1,12 @@
+CREATE TABLE IF NOT EXISTS  t_i171cq_long (
+	id BIGINT(20) NOT NULL,
+	name VARCHAR(30) NULL DEFAULT NULL ,
+	PRIMARY KEY (id)
+);
+
+CREATE TABLE IF NOT EXISTS  t_i171cq_string (
+	id varchar NOT NULL,
+	name VARCHAR(30) NULL DEFAULT NULL ,
+	PRIMARY KEY (id)
+);
+