Browse Source

优化填充处理.

nieqiurong 1 year ago
parent
commit
d3235c32c4

+ 58 - 11
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisParameterHandler.java

@@ -56,8 +56,23 @@ import java.util.Set;
  */
 public class MybatisParameterHandler implements ParameterHandler {
 
+    /**
+     * 填充的key值
+     *
+     * @see #getCollectionFillKeys()
+     * @since 3.5.3.2
+     * @deprecated 3.5.4
+     */
+    @Deprecated
     public static final String[] COLLECTION_KEYS = new String[]{"collection", "coll", "list", "array"};
 
+    /**
+     * 需要填充的集合key值
+     *
+     * @since 3.5.4
+     */
+    private static final Set<String> COLLECTION_FILL_KEYS = new HashSet<>(Arrays.asList(COLLECTION_KEYS));
+
     private final TypeHandlerRegistry typeHandlerRegistry;
     private final MappedStatement mappedStatement;
     private final Object parameterObject;
@@ -221,29 +236,40 @@ public class MybatisParameterHandler implements ParameterHandler {
      */
     @SuppressWarnings({"rawtypes", "unchecked"})
     private Collection<Object> extractParameters(Object parameterObject) {
-        Collection<Object> parameters = new ArrayList<>();
         if (parameterObject instanceof Collection) {
-            parameters = (Collection) parameterObject;
+            return (Collection) parameterObject;
         } else if (ArrayUtils.isArray(parameterObject)) {
-            parameters = toCollection(parameterObject);
+            return toCollection(parameterObject);
         } else if (parameterObject instanceof Map) {
-            Map parameterMap = (Map) parameterObject;
+            Collection<Object> parameters = new ArrayList<>();
+            Map<String, Object> parameterMap = (Map) parameterObject;
             if (parameterMap.containsKey(Constants.ENTITY)) {
                 parameters.add(parameterMap.get(Constants.ENTITY));
             }
             Set<Collection<Object>> objectSet = new HashSet<>();
-            for (String key : COLLECTION_KEYS) {
-                if (parameterMap.containsKey(key)) {
-                    Collection<Object> collection = toCollection(parameterMap.get(key));
-                    if (objectSet.add(collection)) {
-                        parameters.addAll(collection);
+            if (parameterMap.size() > COLLECTION_FILL_KEYS.size()) {
+                for (String key : COLLECTION_FILL_KEYS) {
+                    if (parameterMap.containsKey(key)) {
+                        Collection<Object> collection = toCollection(parameterMap.get(key));
+                        if (objectSet.add(collection)) {
+                            parameters.addAll(collection);
+                        }
                     }
                 }
+            } else {
+                parameterMap.forEach((k, v) -> {
+                    if (COLLECTION_FILL_KEYS.contains(k)) {
+                        Collection<Object> collection = toCollection(v);
+                        if (objectSet.add(collection)) {
+                            parameters.addAll(collection);
+                        }
+                    }
+                });
             }
+            return parameters;
         } else {
-            parameters.add(parameterObject);
+            return Collections.singleton(parameterObject);
         }
-        return parameters;
     }
 
     @SuppressWarnings("unchecked")
@@ -295,4 +321,25 @@ public class MybatisParameterHandler implements ParameterHandler {
             }
         }
     }
+
+    /**
+     * 获取集合特殊key值填充列表
+     *
+     * @return key值列表
+     * @since 3.5.4
+     */
+    public static Set<String> getCollectionFillKeys() {
+        return Collections.unmodifiableSet(COLLECTION_FILL_KEYS);
+    }
+
+    /**
+     * 添加特殊集合Key值填充处理
+     *
+     * @param keys 特殊集合key值
+     * @since 3.5.4
+     */
+    public static void addCollectionFillKeys(String... keys) {
+        COLLECTION_FILL_KEYS.addAll(Arrays.asList(keys));
+    }
+
 }

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

@@ -7,7 +7,6 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
 import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
-import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
 import org.apache.ibatis.builder.xml.XMLMapperBuilder;
 import org.apache.ibatis.io.Resources;
 import org.apache.ibatis.logging.slf4j.Slf4jImpl;

+ 38 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/fill/FillEntity.java

@@ -0,0 +1,38 @@
+package com.baomidou.mybatisplus.test.fill;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * @author nieqiurong 2023年9月29日
+ */
+@Data
+@TableName(value = "t_fill")
+public class FillEntity {
+
+    private Long id;
+
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private String name;
+
+    private transient int seq;
+
+    public FillEntity() {
+    }
+
+    public FillEntity(Long id) {
+        this.id = id;
+    }
+
+    public FillEntity(Long id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    void addSeq(){
+        this.seq ++;
+    }
+
+}

+ 21 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/fill/FillMapper.java

@@ -0,0 +1,21 @@
+package com.baomidou.mybatisplus.test.fill;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @author nieqiurong 2023年9月29日
+ */
+public interface FillMapper extends BaseMapper<FillEntity> {
+
+    void insertBatch1(List<FillEntity> entityList);
+
+    void insertBatch2(@Param("mpList") List<FillEntity> entityList);
+
+    void insertBatch3(@Param("mybatisList") List<FillEntity> entityList);
+
+    void insertBatch4(@Param("list") List<FillEntity> entityList, String a, String b, String c);
+
+}

+ 125 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/fill/FillTest.java

@@ -0,0 +1,125 @@
+package com.baomidou.mybatisplus.test.fill;
+
+import com.baomidou.mybatisplus.core.MybatisParameterHandler;
+import com.baomidou.mybatisplus.core.batch.MybatisBatch;
+import com.baomidou.mybatisplus.core.config.GlobalConfig;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.core.toolkit.MybatisBatchUtils;
+import com.baomidou.mybatisplus.test.BaseDbTest;
+import org.apache.ibatis.reflection.MetaObject;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author nieqiurong 2023年9月29日
+ */
+public class FillTest extends BaseDbTest<FillMapper> {
+
+    static {
+        System.out.println("---------增加一个特殊Key值填充处理列表--------------");
+        MybatisParameterHandler.addCollectionFillKeys("mpList");
+    }
+    @Test
+    void testInsert() {
+        doTest(mapper -> {
+            var entity = new FillEntity();
+            mapper.insert(entity);
+            assertEntity(entity, "insertAdmin", 1);
+        });
+    }
+
+    @Test
+    void testInsertBatch1() {
+        doTest(mapper -> {
+            var entityList = new ArrayList<>(Arrays.asList(new FillEntity(), new FillEntity()));
+            mapper.insertBatch1(entityList);
+            for (FillEntity entity : entityList) {
+                assertEntity(entity, "insertAdmin", 1);
+            }
+        });
+    }
+
+    @Test
+    void testInsertBatch2() {
+        doTest(mapper -> {
+            var entityList = new ArrayList<>(Arrays.asList(new FillEntity(), new FillEntity()));
+            mapper.insertBatch2(entityList);
+            for (FillEntity entity : entityList) {
+                assertEntity(entity, "insertAdmin", 1);
+            }
+        });
+    }
+
+    @Test
+    void testInsertBatch3() {
+        doTest(mapper -> {
+            var entityList = new ArrayList<>(Arrays.asList(new FillEntity(IdWorker.getId()), new FillEntity(IdWorker.getId())));
+            mapper.insertBatch3(entityList);
+            for (FillEntity entity : entityList) {
+                assertEntity(entity, null, 0);
+            }
+        });
+    }
+
+    @Test
+    void testInsertBatch4() {
+        doTest(mapper -> {
+            var entityList = new ArrayList<>(Arrays.asList(new FillEntity(), new FillEntity()));
+            mapper.insertBatch4(entityList, "", "", "");
+            for (FillEntity entity : entityList) {
+                assertEntity(entity, "insertAdmin", 1);
+            }
+        });
+    }
+
+    @Test
+    void testBatch() {
+        var entityList = new ArrayList<>(Arrays.asList(new FillEntity(), new FillEntity()));
+        var method = new MybatisBatch.Method<FillEntity>(FillMapper.class);
+        MybatisBatchUtils.execute(sqlSessionFactory, entityList, method.insert());
+        for (FillEntity entity : entityList) {
+            assertEntity(entity, "insertAdmin", 1);
+        }
+    }
+
+    void assertEntity(FillEntity entity, String name, int seq) {
+        Assertions.assertEquals(entity.getName(), name);
+        Assertions.assertEquals(entity.getSeq(), seq);
+    }
+
+    @Override
+    protected GlobalConfig globalConfig() {
+        GlobalConfig globalConfig = super.globalConfig();
+        globalConfig.setMetaObjectHandler(new MetaObjectHandler() {
+            @Override
+            public void insertFill(MetaObject metaObject) {
+                var entity = (FillEntity) metaObject.getOriginalObject();
+                entity.setName("insertAdmin");
+                entity.addSeq();
+            }
+
+            @Override
+            public void updateFill(MetaObject metaObject) {
+                var entity = (FillEntity) metaObject.getOriginalObject();
+                entity.setName("updateAdmin");
+                entity.addSeq();
+
+            }
+        });
+        return globalConfig;
+    }
+
+    @Override
+    protected List<String> tableSql() {
+        return Arrays.asList("drop table if exists t_fill", "CREATE TABLE IF NOT EXISTS t_fill (" +
+            "id BIGINT NOT NULL," +
+            "name VARCHAR(30) NULL DEFAULT NULL," +
+            "PRIMARY KEY (id))");
+    }
+
+}

+ 1 - 1
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/resultmap/ResultMapTest.java

@@ -43,6 +43,6 @@ public class ResultMapTest extends BaseDbTest<EntityMapper> {
 
     @Override
     protected String mapperXml() {
-        return "com/baomidou/mybatisplus/test/resultmap/entityMapper.xml";
+        return "com/baomidou/mybatisplus/test/resultmap/EntityMapper.xml";
     }
 }

+ 33 - 0
mybatis-plus/src/test/resources/com/baomidou/mybatisplus/test/fill/FillMapper.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.baomidou.mybatisplus.test.fill.FillMapper">
+
+    <insert id="insertBatch1">
+        insert into t_fill(id, name) values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.id}, #{item.name})
+        </foreach>
+    </insert>
+
+    <insert id="insertBatch2">
+        insert into t_fill(id, name) values
+        <foreach collection="mpList" item="item" separator=",">
+            (#{item.id}, #{item.name})
+        </foreach>
+    </insert>
+
+    <insert id="insertBatch3">
+        insert into t_fill(id, name) values
+        <foreach collection="mybatisList" item="item" separator=",">
+            (#{item.id}, #{item.name})
+        </foreach>
+    </insert>
+
+    <insert id="insertBatch4">
+        insert into t_fill(id, name) values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.id}, #{item.name})
+        </foreach>
+    </insert>
+
+</mapper>

+ 0 - 0
mybatis-plus/src/test/resources/com/baomidou/mybatisplus/test/resultmap/entityMapper.xml → mybatis-plus/src/test/resources/com/baomidou/mybatisplus/test/resultmap/EntityMapper.xml