From 7c6fe5f244166a166c08b9ab2ad48aa7c40b8bb0 Mon Sep 17 00:00:00 2001
From: 疯狂的狮子li <15040126243@163.com>
Date: 星期四, 26 八月 2021 09:58:57 +0800
Subject: [PATCH] add 新增 saveOrUpdateAll 方法 可完美替代 saveOrUpdateBatch 高性能

---
 ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/IServicePlus.java    |    2 +
 ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/ServicePlusImpl.java |   53 +++++++++++++++-----------
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java            |   31 ++++++++++++---
 3 files changed, 56 insertions(+), 30 deletions(-)

diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/IServicePlus.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/IServicePlus.java
index 710f11a..7ce40c7 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/IServicePlus.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/IServicePlus.java
@@ -168,5 +168,7 @@
 	}
 
 	boolean saveAll(Collection<T> entityList);
+
+	boolean saveOrUpdateAll(Collection<T> entityList);
 }
 
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/ServicePlusImpl.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/ServicePlusImpl.java
index 99441b5..3a461a8 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/ServicePlusImpl.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/ServicePlusImpl.java
@@ -1,20 +1,21 @@
 package com.ruoyi.common.core.mybatisplus.core;
 
 import cn.hutool.core.bean.copier.CopyOptions;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
+import com.baomidou.mybatisplus.core.toolkit.Assert;
 import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.core.page.PagePlus;
 import com.ruoyi.common.utils.BeanCopyUtils;
+import com.ruoyi.common.utils.reflect.ReflectUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.ResolvableType;
 
 import java.io.Serializable;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -119,31 +120,37 @@
 
 	/**
 	 * 鍗晄ql鎵归噺鎻掑叆( 鍏ㄩ噺濉厖 )
-	 * 閫傜敤浜庢棤鑴戞彃鍏�
 	 */
 	@Override
 	public boolean saveAll(Collection<T> entityList) {
-		ArrayList<T> list = new ArrayList<>();
-		for (T t : entityList) {
-			try {
-				//鑾峰彇灞炴�ф敞瑙g殑value鍊�
-				Field f = t.getClass().getDeclaredField("id");
-				f.setAccessible( true );//璁剧疆鍙互鑼冨洿private
-				Object o = f.get(t);//鑾峰彇鍑篿d鐨勫��
-				System.out.println(o);
-				if (o == null) {
-					//濡傛灉id涓簄ull,鎻掑叆
-					list.add(t);
-				} else {
-					//鍚﹀垯鏇存柊
-					baseMapper.updateById(t);
-				}
+		return baseMapper.insertAll(entityList) == entityList.size();
+	}
 
-			} catch (Exception e) {
-				e.printStackTrace();
+	/**
+	 * 鍏ㄩ噺淇濆瓨鎴栨洿鏂� ( 鎸変富閿尯鍒� )
+	 */
+	@Override
+	public boolean saveOrUpdateAll(Collection<T> entityList) {
+		TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
+		Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
+		String keyProperty = tableInfo.getKeyProperty();
+		Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
+		List<T> addList = new ArrayList<>();
+		List<T> updateList = new ArrayList<>();
+		int row = 0;
+		for (T entity : entityList) {
+			Object id = ReflectUtils.invokeGetter(entity, keyProperty);
+			if (ObjectUtil.isNull(id)) {
+				addList.add(entity);
+			} else {
+				updateList.add(entity);
 			}
 		}
-		return baseMapper.insertAll(list) == list.size();
+		if (updateBatchById(updateList)) {
+			row += updateList.size();
+		}
+		row += baseMapper.insertAll(addList);
+		return row == entityList.size();
 	}
 
 	/**
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java
index db96797..2db9961 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java
@@ -35,21 +35,38 @@
      * 鏂板鎵归噺鏂规硶 鍙畬缇庢浛浠� saveBatch 绉掔骇鎻掑叆涓婁竾鏁版嵁 (瀵筸ysql璐熻嵎杈冨ぇ)
      */
 	@ApiOperation(value = "鏂板鎵归噺鏂规硶")
-    @PostMapping()
+    @PostMapping("/add")
 //	@DataSource(DataSourceType.SLAVE)
     public AjaxResult<Void> add() {
 		List<TestDemo> list = new ArrayList<>();
 		for (int i = 0; i < 10; i++) {
-			TestDemo testDemo = new TestDemo();
-			if (i % 2 == 0) {
-				list.add(testDemo.setId((long) i + 1).setTestKey("鎵归噺鏇存柊").setValue("鎵归噺鏇存柊"));
-			} else {
-				list.add(testDemo.setOrderNum(-1L).setTestKey("鎵归噺鏂板").setValue("娴嬭瘯鏂板"));
-			}
+			list.add(new TestDemo().setOrderNum(-1L).setTestKey("鎵归噺鏂板").setValue("娴嬭瘯鏂板"));
 		}
         return toAjax(iTestDemoService.saveAll(list) ? 1 : 0);
     }
 
+	/**
+	 * 鏂板鎴栨洿鏂� 鍙畬缇庢浛浠� saveOrUpdateBatch 楂樻�ц兘
+	 */
+	@ApiOperation(value = "鏂板鎴栨洿鏂版壒閲忔柟娉�")
+	@PostMapping("/addOrUpdate")
+//	@DataSource(DataSourceType.SLAVE)
+	public AjaxResult<Void> addOrUpdate() {
+		List<TestDemo> list = new ArrayList<>();
+		for (int i = 0; i < 1000; i++) {
+			list.add(new TestDemo().setOrderNum(-1L).setTestKey("鎵归噺鏂板").setValue("娴嬭瘯鏂板"));
+		}
+		iTestDemoService.saveAll(list);
+		for (int i = 0; i < list.size(); i++) {
+			TestDemo testDemo = list.get(i);
+			testDemo.setTestKey("鎵归噺鏂板鎴栦慨鏀�").setValue("鎵归噺鏂板鎴栦慨鏀�");
+			if (i % 2 == 0) {
+				testDemo.setId(null);
+			}
+		}
+		return toAjax(iTestDemoService.saveOrUpdateAll(list) ? 1 : 0);
+	}
+
     /**
      * 鍒犻櫎鎵归噺鏂规硶
      */

--
Gitblit v1.9.3