From a58caadbaacaa04b38a3c14563addbe7e24b2ff5 Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Sun, 3 Aug 2025 15:42:16 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E6=96=B0=E5=A2=9EResultHandler=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mybatis/handler/BatchResultHandler.java | 101 ++++++++++++++++++ .../mybatis/handler/FilterResultHandler.java | 64 +++++++++++ .../mybatis/handler/SimpleResultHandler.java | 48 +++++++++ 3 files changed, 213 insertions(+) create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/BatchResultHandler.java create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/FilterResultHandler.java create mode 100644 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/SimpleResultHandler.java diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/BatchResultHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/BatchResultHandler.java new file mode 100644 index 000000000..bd505a038 --- /dev/null +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/BatchResultHandler.java @@ -0,0 +1,101 @@ +package org.dromara.common.mybatis.handler; + +import cn.hutool.core.collection.CollUtil; +import org.apache.ibatis.session.ResultContext; +import org.apache.ibatis.session.ResultHandler; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +/** + * 批量结果处理器 + * + *
将查询结果按指定批量大小缓存, + * 达到批量大小时调用批量消费函数进行批量处理,避免一次性加载全部数据导致内存压力过大 + * + *
适用于导出Excel、批量写库、定时上报等需要批量操作场景, + * 能有效降低内存使用并提升处理性能 + * + *
使用须知: 注意:长时间的批量处理操作(如写Excel、写数据库或调用远程接口)可能导致数据库连接超时或断开,
+ * 以及MyBatis查询线程阻塞,影响系统性能和稳定性。
+ *
+ * 因此推荐:
+ * 这样能有效保障系统的高性能和稳定运行
+ */
+ private final Consumer
+ * 通过传入的过滤条件({@link Predicate})筛选查询结果,
+ * 仅对满足条件的结果调用消费函数进行处理
+ *
+ * 适用于需要对查询结果做条件过滤再处理的场景
+ * 避免无用数据进入后续处理逻辑,提高效率
+ *
+ * @param 适用于无需缓存或批量处理,直接对结果逐条消费的场景
+ * 逻辑简单直接,实时处理每条数据
+ *
+ * @param
+ * 1. 构造时传入非空的批量消费函数和合法的批量大小(>0)
+ * 2. 结果回调时自动缓存并批量触发消费函数
+ * 3. 查询完成后务必调用 {@link #flush()},处理剩余不足批量的数据,避免数据遗漏
+ *
+ * @param
+ *
+ *
+ * > batchConsumer;
+
+ /**
+ * 批量大小,必须大于0
+ */
+ private final int batchSize;
+
+ /**
+ * 当前缓存数据
+ */
+ private final List
> batchConsumer, int batchSize) {
+ if (batchConsumer == null) {
+ throw new NullPointerException("batchConsumer不能为null");
+ }
+ if (batchSize <= 0) {
+ throw new IllegalArgumentException("batchSize必须大于0");
+ }
+ this.batchConsumer = batchConsumer;
+ this.batchSize = batchSize;
+ this.buffer = new ArrayList<>(batchSize);
+ }
+
+ /**
+ * MyBatis 查询结果回调,缓存单条结果,
+ * 达到批量大小时触发批量消费函数处理缓存数据
+ *
+ * @param context 查询结果上下文,包含单条结果
+ */
+ @Override
+ public void handleResult(ResultContext extends T> context) {
+ buffer.add(context.getResultObject());
+ if (buffer.size() >= batchSize) {
+ flush();
+ }
+ }
+
+ /**
+ * 刷新缓存,触发批量消费函数处理剩余数据,
+ * 通常查询结束后调用,确保所有数据均被处理
+ */
+ public void flush() {
+ if (CollUtil.isNotEmpty(buffer)) {
+ batchConsumer.accept(new ArrayList<>(buffer));
+ buffer.clear();
+ }
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/FilterResultHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/FilterResultHandler.java
new file mode 100644
index 000000000..6496458d6
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/FilterResultHandler.java
@@ -0,0 +1,64 @@
+package org.dromara.common.mybatis.handler;
+
+import org.apache.ibatis.session.ResultContext;
+import org.apache.ibatis.session.ResultHandler;
+
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+
+/**
+ * 过滤处理器
+ *