Browse Source

多租户二级缓存思路.

nieqiuqiu 5 years ago
parent
commit
1f1ef62e41

+ 44 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/tenant/CustomCacheExecutor.java

@@ -0,0 +1,44 @@
+package com.baomidou.mybatisplus.test.h2.tenant;
+
+import com.baomidou.mybatisplus.core.executor.MybatisCachingExecutor;
+import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
+import org.apache.ibatis.cache.CacheKey;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlCommandType;
+import org.apache.ibatis.session.RowBounds;
+
+import java.util.Objects;
+
+
+/**
+ * @author nieqiuqiu 2020/6/15
+ */
+public class CustomCacheExecutor extends MybatisCachingExecutor {
+
+    private TenantHandler tenantHandler;
+
+    public CustomCacheExecutor(Executor delegate, TenantHandler tenantHandler) {
+        super(delegate);
+        this.tenantHandler = tenantHandler;
+    }
+
+    @Override
+    public CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {
+        if (ms.getSqlCommandType() == SqlCommandType.SELECT) {
+            CacheKey cacheKey = super.createCacheKey(ms, parameterObject, rowBounds, boundSql);
+            cacheKey.update(Objects.toString(tenantHandler.getTenantId(true)));
+            return cacheKey;
+        }
+        return super.createCacheKey(ms, parameterObject, rowBounds, boundSql);
+    }
+
+    @Override
+    protected CacheKey getCountCacheKey(MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject, RowBounds rowBounds) {
+        CacheKey countCacheKey = super.getCountCacheKey(mappedStatement, boundSql, parameterObject, rowBounds);
+        countCacheKey.update(Objects.toString(tenantHandler.getTenantId(true)));
+        return countCacheKey;
+    }
+
+}

+ 33 - 9
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/tenant/TenantConfig.java

@@ -1,6 +1,9 @@
 package com.baomidou.mybatisplus.test.h2.tenant;
 
 import com.baomidou.mybatisplus.core.MybatisConfiguration;
+import com.baomidou.mybatisplus.core.executor.MybatisBatchExecutor;
+import com.baomidou.mybatisplus.core.executor.MybatisReuseExecutor;
+import com.baomidou.mybatisplus.core.executor.MybatisSimpleExecutor;
 import com.baomidou.mybatisplus.core.parser.ISqlParser;
 import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
@@ -8,8 +11,10 @@ import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
 import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
 import net.sf.jsqlparser.expression.Expression;
 import net.sf.jsqlparser.expression.LongValue;
+import org.apache.ibatis.executor.Executor;
 import org.apache.ibatis.session.ExecutorType;
 import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.transaction.Transaction;
 import org.apache.ibatis.type.EnumOrdinalTypeHandler;
 import org.apache.ibatis.type.JdbcType;
 import org.mybatis.spring.annotation.MapperScan;
@@ -34,15 +39,6 @@ public class TenantConfig {
     public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
         MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
         sqlSessionFactory.setDataSource(dataSource);
-        MybatisConfiguration configuration = new MybatisConfiguration();
-        configuration.setJdbcTypeForNull(JdbcType.NULL);
-        configuration.setMapUnderscoreToCamelCase(true);
-        configuration.setDefaultExecutorType(ExecutorType.REUSE);
-        configuration.setDefaultEnumTypeHandler(EnumOrdinalTypeHandler.class);
-        configuration.setCacheEnabled(true);
-        sqlSessionFactory.setConfiguration(configuration);
-        PaginationInterceptor pagination = new PaginationInterceptor();
-        List<ISqlParser> sqlParserList = new ArrayList<>();
         TenantSqlParser tenantSqlParser = new TenantSqlParser();
         tenantSqlParser.setTenantHandler(new TenantHandler() {
             @Override
@@ -60,6 +56,34 @@ public class TenantConfig {
                 return false;
             }
         });
+        MybatisConfiguration configuration = new MybatisConfiguration() {
+            @Override
+            public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
+                executorType = executorType == null ? defaultExecutorType : executorType;
+                executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
+                Executor executor;
+                if (ExecutorType.BATCH == executorType) {
+                    executor = new MybatisBatchExecutor(this, transaction);
+                } else if (ExecutorType.REUSE == executorType) {
+                    executor = new MybatisReuseExecutor(this, transaction);
+                } else {
+                    executor = new MybatisSimpleExecutor(this, transaction);
+                }
+                if (cacheEnabled) {
+                    executor = new CustomCacheExecutor(executor, tenantSqlParser.getTenantHandler());
+                }
+                executor = (Executor) interceptorChain.pluginAll(executor);
+                return executor;
+            }
+        };
+        configuration.setJdbcTypeForNull(JdbcType.NULL);
+        configuration.setMapUnderscoreToCamelCase(true);
+        configuration.setDefaultExecutorType(ExecutorType.REUSE);
+        configuration.setDefaultEnumTypeHandler(EnumOrdinalTypeHandler.class);
+        configuration.setCacheEnabled(true);
+        sqlSessionFactory.setConfiguration(configuration);
+        PaginationInterceptor pagination = new PaginationInterceptor();
+        List<ISqlParser> sqlParserList = new ArrayList<>();
         sqlParserList.add(tenantSqlParser);
         pagination.setSqlParserList(sqlParserList);
         sqlSessionFactory.setPlugins(pagination);

+ 2 - 2
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/tenant/TenantTest.java

@@ -26,7 +26,7 @@ class TenantTest {
     @Autowired
     private IStudentService studentService;
 
-    //    @Test
+    @Test
     void testSimple() {
         TenantConfig.TENANT_ID = 2L;
         Student student1 = studentService.getById(1L);
@@ -40,7 +40,7 @@ class TenantTest {
         Assertions.assertNotNull(student2);
     }
 
-    //    @Test
+    @Test
     void testPage() {
         TenantConfig.TENANT_ID = 2L;
         Page<Student> page1 = studentService.page(new Page<>(0, 10), new QueryWrapper<>());