diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java index d9932b0d1..3d1642803 100644 --- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java +++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java @@ -1,11 +1,14 @@ package org.dromara.common.encrypt.interceptor; import lombok.AllArgsConstructor; +import org.apache.ibatis.cursor.Cursor; import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.plugin.*; import org.dromara.common.encrypt.core.EncryptedFieldProcessor; +import java.io.IOException; import java.sql.Statement; +import java.util.Iterator; import java.util.Properties; /** @@ -13,10 +16,10 @@ import java.util.Properties; * * @author Lion Li */ -@Intercepts({@Signature( - type = ResultSetHandler.class, - method = "handleResultSets", - args = {Statement.class}) +@Intercepts({ + @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}), + // MP 3.5.17 起 selectOne/selectVoOne 走游标,需一并拦截解密 + @Signature(type = ResultSetHandler.class, method = "handleCursorResultSets", args = {Statement.class}) }) @AllArgsConstructor public class MybatisDecryptInterceptor implements Interceptor { @@ -32,11 +35,13 @@ public class MybatisDecryptInterceptor implements Interceptor { */ @Override public Object intercept(Invocation invocation) throws Throwable { - // 获取执行mysql执行结果 Object result = invocation.proceed(); if (result == null) { return null; } + if (result instanceof Cursor cursor) { + return new DecryptCursor<>(cursor, encryptedFieldProcessor); + } encryptedFieldProcessor.decrypt(result); return result; } @@ -61,4 +66,52 @@ public class MybatisDecryptInterceptor implements Interceptor { public void setProperties(Properties properties) { } + + /** + * 查询结果解密游标,保持 MyBatis 游标的惰性读取语义。 + * + * @param 查询结果类型 + */ + private record DecryptCursor(Cursor delegate, EncryptedFieldProcessor encryptedFieldProcessor) + implements Cursor { + + @Override + public boolean isOpen() { + return delegate.isOpen(); + } + + @Override + public boolean isConsumed() { + return delegate.isConsumed(); + } + + @Override + public int getCurrentIndex() { + return delegate.getCurrentIndex(); + } + + @Override + public Iterator iterator() { + Iterator iterator = delegate.iterator(); + return new Iterator<>() { + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public T next() { + T result = iterator.next(); + encryptedFieldProcessor.decrypt(result); + return result; + } + }; + } + + @Override + public void close() throws IOException { + delegate.close(); + } + } }