浏览代码

优化 JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution) 拆分为单个泛型、集合泛型两个方法

hubin 4 年之前
父节点
当前提交
c1f5aa571a

+ 37 - 7
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/AbstractWrapper.java

@@ -27,10 +27,7 @@ import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
 import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils;
 import com.baomidou.mybatisplus.core.toolkit.sql.StringEscape;
 
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.BiPredicate;
 import java.util.function.Consumer;
@@ -309,6 +306,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
             () -> String.format("(%s)", inValue)));
     }
 
+    @Deprecated
     @Override
     public Children groupBy(boolean condition, R column, R... columns) {
         return maybeDo(condition, () -> {
@@ -321,11 +319,12 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
         });
     }
 
+    @Deprecated
     @Override
     public Children orderBy(boolean condition, boolean isAsc, R column, R... columns) {
         return maybeDo(condition, () -> {
             final SqlKeyword mode = isAsc ? ASC : DESC;
-            appendSqlSegments(ORDER_BY, columnToSqlSegment(column), mode);
+            appendSqlSegments(ORDER_BY, columnToSqlSegment(columnSqlInjectFilter(column)), mode);
             if (ArrayUtils.isNotEmpty(columns)) {
                 Arrays.stream(columns).forEach(c -> appendSqlSegments(ORDER_BY,
                     columnToSqlSegment(columnSqlInjectFilter(c)), mode));
@@ -333,6 +332,28 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
         });
     }
 
+    @Override
+    public Children groupBy(boolean condition, R column) {
+        return maybeDo(condition, () -> appendSqlSegments(GROUP_BY, () -> columnToString(column)));
+    }
+
+    @Override
+    public Children groupBy(boolean condition, List<R> columns) {
+        return maybeDo(condition, () -> appendSqlSegments(GROUP_BY, () -> columnsToString(columns)));
+    }
+
+    @Override
+    public Children orderBy(boolean condition, boolean isAsc, R column) {
+        return maybeDo(condition, () -> appendSqlSegments(ORDER_BY, columnToSqlSegment(columnSqlInjectFilter(column)),
+            isAsc ? ASC : DESC));
+    }
+
+    @Override
+    public Children orderBy(boolean condition, boolean isAsc, List<R> columns) {
+        return maybeDo(condition, () -> columns.forEach(c -> appendSqlSegments(ORDER_BY,
+            columnToSqlSegment(columnSqlInjectFilter(c)), isAsc ? ASC : DESC)));
+    }
+
     /**
      * 字段 SQL 注入过滤处理,子类重写实现过滤逻辑
      *
@@ -582,13 +603,22 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
         return (String) column;
     }
 
+    /**
+     * 不推荐使用, JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
+     */
+    @Deprecated
+    protected String columnsToString(R... columns) {
+        return Arrays.stream(columns).map(this::columnToString).collect(joining(StringPool.COMMA));
+    }
+
     /**
      * 多字段转换为逗号 "," 分割字符串
      *
      * @param columns 多字段
      */
-    protected String columnsToString(R... columns) {
-        return Arrays.stream(columns).map(this::columnToString).collect(joining(StringPool.COMMA));
+    @Deprecated
+    protected String columnsToString(List<R> columns) {
+        return columns.stream().map(this::columnToString).collect(joining(StringPool.COMMA));
     }
 
     @Override

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

@@ -17,6 +17,7 @@ package com.baomidou.mybatisplus.core.conditions.interfaces;
 
 import java.io.Serializable;
 import java.util.Collection;
+import java.util.List;
 import java.util.function.Consumer;
 
 /**
@@ -180,74 +181,168 @@ public interface Func<Children, R> extends Serializable {
      */
     Children notInSql(boolean condition, R column, String inValue);
 
+
     /**
-     * ignore
+     * 分组:GROUP BY 字段, ...
+     * <p>例: groupBy("id")</p>
+     *
+     * @param condition 执行条件
+     * @param column    单个字段
+     * @return children
      */
-    default Children groupBy(R column, R... columns) {
-        return groupBy(true, column, columns);
+    Children groupBy(boolean condition, R column);
+
+    default Children groupBy(R column) {
+        return groupBy(true, column);
     }
 
+
     /**
      * 分组:GROUP BY 字段, ...
-     * <p>例: groupBy("id", "name")</p>
+     * <p>例: groupBy(Arrays.asList("id", "name"))</p>
      *
      * @param condition 执行条件
-     * @param column    单个字段
      * @param columns   字段数组
      * @return children
      */
+    Children groupBy(boolean condition, List<R> columns);
+
+    default Children groupBy(List<R> columns) {
+        return groupBy(true, columns);
+    }
+
+    @Deprecated
+    default Children groupBy(R column, R... columns) {
+        return groupBy(true, column, columns);
+    }
+
+    /**
+     * 分组:GROUP BY 字段, ...
+     * 不推荐使用, JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
+     */
+    @Deprecated
     Children groupBy(boolean condition, R column, R... columns);
 
     /**
-     * ignore
+     * 排序:ORDER BY 字段, ... ASC
+     * <p>例: orderByAsc(true, "id")</p>
+     *
+     * @param condition 执行条件
+     * @param column    单个字段
+     * @return children
      */
-    default Children orderByAsc(R column, R... columns) {
-        return orderByAsc(true, column, columns);
+    default Children orderByAsc(boolean condition, R column) {
+        return orderBy(condition, true, column);
+    }
+
+    default Children orderByAsc(R column) {
+        return orderByAsc(true, column);
     }
 
     /**
      * 排序:ORDER BY 字段, ... ASC
-     * <p>例: orderByAsc("id", "name")</p>
+     * <p>例: orderByAsc(true, Arrays.asList("id", "name"))</p>
      *
      * @param condition 执行条件
-     * @param column    单个字段
      * @param columns   字段数组
      * @return children
      */
+    default Children orderByAsc(boolean condition, List<R> columns) {
+        return orderBy(condition, true, columns);
+    }
+
+    default Children orderByAsc(List<R> columns) {
+        return orderByAsc(true, columns);
+    }
+
+    @Deprecated
+    default Children orderByAsc(R column, R... columns) {
+        return orderByAsc(true, column, columns);
+    }
+
+    /**
+     * 排序:ORDER BY 字段, ... ASC
+     * 不推荐使用, JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
+     */
+    @Deprecated
     default Children orderByAsc(boolean condition, R column, R... columns) {
         return orderBy(condition, true, column, columns);
     }
 
+
     /**
-     * ignore
+     * 排序:ORDER BY 字段, ... DESC
+     * <p>例: orderByDesc(true, "id")</p>
+     *
+     * @param condition 执行条件
+     * @param column    字段
+     * @return children
      */
-    default Children orderByDesc(R column, R... columns) {
-        return orderByDesc(true, column, columns);
+    default Children orderByDesc(boolean condition, R column) {
+        return orderBy(condition, false, column);
+    }
+
+    default Children orderByDesc(R column) {
+        return orderByDesc(true, column);
     }
 
     /**
      * 排序:ORDER BY 字段, ... DESC
-     * <p>例: orderByDesc("id", "name")</p>
+     * <p>例: orderByDesc(true, Arrays.asList("id", "name"))</p>
      *
      * @param condition 执行条件
-     * @param column    单个字段
-     * @param columns   字段数组
+     * @param columns   字段列表
      * @return children
      */
+    default Children orderByDesc(boolean condition, List<R> columns) {
+        return orderBy(condition, false, columns);
+    }
+
+    default Children orderByDesc(List<R> columns) {
+        return orderByDesc(true, columns);
+    }
+
+    @Deprecated
+    default Children orderByDesc(R column, R... columns) {
+        return orderByDesc(true, column, columns);
+    }
+
+    /**
+     * 排序:ORDER BY 字段, ... DESC
+     * 不推荐使用, JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
+     */
+    @Deprecated
     default Children orderByDesc(boolean condition, R column, R... columns) {
         return orderBy(condition, false, column, columns);
     }
 
     /**
      * 排序:ORDER BY 字段, ...
-     * <p>例: orderBy(true, "id", "name")</p>
+     * <p>例: orderBy(true, "id")</p>
      *
      * @param condition 执行条件
      * @param isAsc     是否是 ASC 排序
      * @param column    单个字段
-     * @param columns   字段数组
      * @return children
      */
+    Children orderBy(boolean condition, boolean isAsc, R column);
+
+    /**
+     * 排序:ORDER BY 字段, ...
+     * <p>例: orderBy(true, Arrays.asList("id", "name"))</p>
+     *
+     * @param condition 执行条件
+     * @param isAsc     是否是 ASC 排序
+     * @param columns   字段列表
+     * @return children
+     */
+    Children orderBy(boolean condition, boolean isAsc, List<R> columns);
+
+    /**
+     * 排序:ORDER BY 字段, ...
+     * 不推荐使用, JDK 默认不推荐泛型数组,会引起 Java堆污染(Heap Pollution)
+     */
+    @Deprecated
     Children orderBy(boolean condition, boolean isAsc, R column, R... columns);
 
     /**

+ 5 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableFieldInfo.java

@@ -266,7 +266,11 @@ public class TableFieldInfo implements Constants {
         this.sqlSelect = column;
         if (needAs) {
             // 存在指定转换属性
-            this.sqlSelect += String.format("%s\"%s\"", AS, tableField.property());
+            String propertyFormat = dbConfig.getPropertyFormat();
+            if (StringUtils.isBlank(propertyFormat)) {
+                propertyFormat = "%s";
+            }
+            this.sqlSelect += (AS + String.format(propertyFormat, tableField.property()));
         } else if (tableInfo.getResultMap() == null && !tableInfo.isAutoInitResultMap() &&
             TableInfoHelper.checkRelated(tableInfo.isUnderCamel(), this.property, this.column)) {
             /* 未设置 resultMap 也未开启自动构建 resultMap, 字段规则又不符合 mybatis 的自动封装规则 */

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

@@ -25,6 +25,7 @@ import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
 import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import java.util.function.BiPredicate;
 import java.util.function.Consumer;
@@ -199,18 +200,44 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
         return typedThis;
     }
 
+    @Deprecated
     @Override
     public Children groupBy(boolean condition, R column, R... columns) {
         getWrapper().groupBy(condition, column, columns);
         return typedThis;
     }
 
+    @Override
+    public Children groupBy(boolean condition, R column) {
+        getWrapper().groupBy(condition, column);
+        return typedThis;
+    }
+
+    @Override
+    public Children groupBy(boolean condition, List<R> columns) {
+        getWrapper().groupBy(condition, columns);
+        return typedThis;
+    }
+
+    @Deprecated
     @Override
     public Children orderBy(boolean condition, boolean isAsc, R column, R... columns) {
         getWrapper().orderBy(condition, isAsc, column, columns);
         return typedThis;
     }
 
+    @Override
+    public Children orderBy(boolean condition, boolean isAsc, R column) {
+        getWrapper().orderBy(condition, isAsc, column);
+        return typedThis;
+    }
+
+    @Override
+    public Children orderBy(boolean condition, boolean isAsc, List<R> columns) {
+        getWrapper().orderBy(condition, isAsc, columns);
+        return typedThis;
+    }
+
     @Override
     public Children having(boolean condition, String sqlHaving, Object... params) {
         getWrapper().having(condition, sqlHaving, params);

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

@@ -486,6 +486,7 @@ class H2UserTest extends BaseTest {
     void testLambdaWrapperClear() {
         userService.save(new H2User("小红", AgeEnum.TWO));
         LambdaQueryWrapper<H2User> lambdaQueryWrapper = new QueryWrapper<H2User>().lambda().eq(H2User::getName, "小宝");
+        lambdaQueryWrapper.orderByDesc(H2User::getName);
         Assertions.assertEquals(0, userService.count(lambdaQueryWrapper));
         lambdaQueryWrapper.clear();
         lambdaQueryWrapper.eq(H2User::getName, "小红");