yumeng 1 day ago
parent
commit
10faccca57

+ 0 - 60
jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/service/SimpleTiFlashInterceptor.java

@@ -1,60 +0,0 @@
-package org.jeecg.ctop.material.service;
-
-
-import org.apache.ibatis.executor.Executor;
-import org.apache.ibatis.mapping.MappedStatement;
-import org.apache.ibatis.plugin.*;
-        import org.springframework.stereotype.Component;
-import java.sql.Connection;
-import java.sql.Statement;
-import java.util.Properties;
-
-@Intercepts({
-        @Signature(type = Executor.class, method = "query",
-                args = {MappedStatement.class, Object.class,
-                        org.apache.ibatis.session.RowBounds.class,
-                        org.apache.ibatis.session.ResultHandler.class})
-})
-@Component
-public class SimpleTiFlashInterceptor implements Interceptor {
-
-    @Override
-    public Object intercept(Invocation invocation) throws Throwable {
-        try {
-            // 获取连接并设置TiFlash
-            Object target = invocation.getTarget();
-            if (target instanceof Executor) {
-                Executor executor = (Executor) target;
-
-                // 反射获取连接
-                java.lang.reflect.Field transactionField =
-                        executor.getClass().getDeclaredField("transaction");
-                transactionField.setAccessible(true);
-                Object transaction = transactionField.get(executor);
-
-                java.lang.reflect.Field connectionField =
-                        transaction.getClass().getDeclaredField("connection");
-                connectionField.setAccessible(true);
-                Connection connection = (Connection) connectionField.get(transaction);
-
-                // 执行设置语句
-                try (Statement stmt = connection.createStatement()) {
-                    stmt.execute("SET session tidb_isolation_read_engines = 'tiflash,tidb'");
-                }
-            }
-        } catch (Exception e) {
-            // 忽略异常,不中断正常流程
-        }
-
-        return invocation.proceed();
-    }
-
-    @Override
-    public Object plugin(Object target) {
-        return Plugin.wrap(target, this);
-    }
-
-    @Override
-    public void setProperties(Properties properties) {
-    }
-}

+ 111 - 0
jeecg-boot-material-view/src/main/java/org/jeecg/ctop/material/service/impl/TiFlashInterceptor.java

@@ -0,0 +1,111 @@
+package org.jeecg.ctop.material.service.impl;
+
+
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlCommandType;
+import org.apache.ibatis.plugin.*;
+import org.springframework.stereotype.Component;
+import java.sql.Connection;
+import java.sql.Statement;
+import java.util.Properties;
+
+/**
+ * MyBatis拦截器,在执行SQL前设置TiFlash引擎
+ * 最简单的TiFlash配置方案
+ */
+@Intercepts({
+        @Signature(type = Executor.class, method = "query",
+                args = {MappedStatement.class, Object.class,
+                        org.apache.ibatis.session.RowBounds.class,
+                        org.apache.ibatis.session.ResultHandler.class}),
+        @Signature(type = Executor.class, method = "update",
+                args = {MappedStatement.class, Object.class})
+})
+@Component  // 关键:添加@Component注解让Spring管理
+public class TiFlashInterceptor implements Interceptor {
+
+    private static final String SET_SQL =
+            "SET session tidb_isolation_read_engines = 'tiflash,tidb'";
+
+    // ThreadLocal记录每个连接是否已设置,避免重复设置
+    private ThreadLocal<Boolean> tiFlashSet = ThreadLocal.withInitial(() -> false);
+
+    @Override
+    public Object intercept(Invocation invocation) throws Throwable {
+        try {
+            // 获取MappedStatement
+            MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
+
+            // 只对SELECT查询设置TiFlash(可选,根据需求调整)
+            if (ms.getSqlCommandType() == SqlCommandType.SELECT) {
+                setTiFlashIfNeeded(invocation);
+            }
+            // 如果要对所有SQL都设置,可以去掉上面的if判断
+
+        } catch (Exception e) {
+            // 捕获异常但不中断SQL执行
+            System.err.println("TiFlash拦截器异常: " + e.getMessage());
+        }
+
+        // 继续执行原始SQL
+        return invocation.proceed();
+    }
+
+    /**
+     * 设置TiFlash引擎(如果需要)
+     */
+    private void setTiFlashIfNeeded(Invocation invocation) {
+        try {
+            // 检查是否已设置
+            if (tiFlashSet.get()) {
+                return; // 已设置,跳过
+            }
+
+            // 获取数据库连接
+            Connection connection = getConnection(invocation);
+            if (connection != null) {
+                try (Statement stmt = connection.createStatement()) {
+                    stmt.execute(SET_SQL);
+                    tiFlashSet.set(true); // 标记已设置
+                    System.out.println("✅ TiFlash引擎已设置");
+                }
+            }
+        } catch (Exception e) {
+            System.err.println("设置TiFlash失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 通过反射获取当前数据库连接
+     */
+    private Connection getConnection(Invocation invocation) throws Exception {
+        // 获取Executor对象
+        Executor executor = (Executor) invocation.getTarget();
+
+        // 反射获取transaction字段
+        java.lang.reflect.Field transactionField =
+                Executor.class.getDeclaredField("transaction");
+        transactionField.setAccessible(true);
+        Object transaction = transactionField.get(executor);
+
+        // 反射获取connection字段
+        java.lang.reflect.Field connectionField =
+                transaction.getClass().getDeclaredField("connection");
+        connectionField.setAccessible(true);
+
+        return (Connection) connectionField.get(transaction);
+    }
+
+    @Override
+    public Object plugin(Object target) {
+        // 包装目标对象
+        return Plugin.wrap(target, this);
+    }
+
+    @Override
+    public void setProperties(Properties properties) {
+        // 可以读取配置文件中的属性
+        System.out.println("TiFlash拦截器初始化...");
+    }
+}