From 43a5e08959929eb5798fd5f297a243b4426e53c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Tue, 30 May 2023 15:42:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=A8=E6=80=81=E8=A1=A8?= =?UTF-8?q?=E5=90=8D=E7=9A=84=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/.vitepress/config.ts | 1 + docs/zh/core/dynamic-table.md | 46 +++++++++++++++++++ .../mybatisflex/core/table/TableManager.java | 18 ++++---- .../coretest/AccountSqlTester.java | 8 +++- 4 files changed, 63 insertions(+), 10 deletions(-) create mode 100644 docs/zh/core/dynamic-table.md diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 893e1f2a..569da4b2 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -87,6 +87,7 @@ export default defineConfig({ {text: '字段加密', link: '/zh/core/columns-encrypt'}, {text: '字典回写', link: '/zh/core/columns-dict'}, {text: '枚举属性', link: '/zh/core/enum-property'}, + {text: '动态表名', link: '/zh/core/dynamic-table'}, {text: '多租户', link: '/zh/core/multi-tenancy'}, ] }, diff --git a/docs/zh/core/dynamic-table.md b/docs/zh/core/dynamic-table.md new file mode 100644 index 00000000..dcd83620 --- /dev/null +++ b/docs/zh/core/dynamic-table.md @@ -0,0 +1,46 @@ +# 动态表名 + +动态表名指的是用户在对数据进行 增删改查 的时候,传入表名能够根据上下文信息(比如用户信息、应用信息)等,动态修改当前的表。 + +## 使用场景 + +- 1、多租户,不同的租户拥有不同的表 +- 2、分库分表,减轻数据压力 + +## 如何使用 + +在应用启动时,通过调用 `TableManager.setDynamicTableProcessor()` 配置动态表名处理器 `DynamicTableProcessor` 即可,如下代码所示: + +```java +TableManager.setDynamicTableProcessor(new DynamicTableProcessor() { + @Override + public String process(String tableName) { + return tableName + "_01"; + } +}); +``` + +通过以上配置后,我们对数据库进行增删改查,MyBatis-Flex 都会调用 `DynamicTableProcessor.process` 方法,获得最新的表名进行 SQL 构建操作。因此,我们应该在 `process` 方法中, +判断当前的上下文(用户信息、应用信息)等,动态的返回对应的表名。 + +在某些情况下,我们临时修改映射关系,而非通过 `DynamicTableProcessor.process` 方法获取,可以通过如下配置: + +```java +TableManager.setHintTableMapping("tb_account", "tb_account_01") +``` +那么此时,当前线程不再通过 `DynamicTableProcessor` 去获取。 + +## 动态 Schema + +动态 Schema 和动态表名类似,通过 `TableManager.setDynamicSchemaProcessor()` 配置动态 Schema 处理器 `DynamicSchemaProcessor` 即可,如下代码所示: + +```java +TableManager.setDynamicSchemaProcessor(new DynamicSchemaProcessor() { + @Override + public String process(String schema) { + return schema + "_01"; + } +}); +``` + +动态 Schema 的配置,只对使用了注解 `@Table(schema="xxx")` 的 Entity 有效。 \ No newline at end of file diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java index ef97600c..048dc4b6 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java @@ -22,21 +22,14 @@ import java.util.Map; public class TableManager { - private static DynamicSchemaProcessor dynamicSchemaProcessor; + private static DynamicTableProcessor dynamicTableProcessor; + private static DynamicSchemaProcessor dynamicSchemaProcessor; private static final ThreadLocal> tableNameMappingTL = ThreadLocal.withInitial(HashMap::new); private static final ThreadLocal> schemaMappingTL = ThreadLocal.withInitial(HashMap::new); - public static DynamicSchemaProcessor getDynamicSchemaProcessor() { - return dynamicSchemaProcessor; - } - - public static void setDynamicSchemaProcessor(DynamicSchemaProcessor dynamicSchemaProcessor) { - TableManager.dynamicSchemaProcessor = dynamicSchemaProcessor; - } - public static DynamicTableProcessor getDynamicTableProcessor() { return dynamicTableProcessor; } @@ -45,6 +38,13 @@ public class TableManager { TableManager.dynamicTableProcessor = dynamicTableProcessor; } + public static DynamicSchemaProcessor getDynamicSchemaProcessor() { + return dynamicSchemaProcessor; + } + + public static void setDynamicSchemaProcessor(DynamicSchemaProcessor dynamicSchemaProcessor) { + TableManager.dynamicSchemaProcessor = dynamicSchemaProcessor; + } public static void setHintTableMapping(String tableName, String mappingTable) { tableNameMappingTL.get().put(tableName, mappingTable); diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java index 398295a1..9af5cb83 100644 --- a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java @@ -6,6 +6,7 @@ import com.mybatisflex.core.dialect.LimitOffsetProcessor; import com.mybatisflex.core.dialect.impl.CommonsDialectImpl; import com.mybatisflex.core.query.CPI; import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.table.DynamicTableProcessor; import com.mybatisflex.core.table.TableInfo; import com.mybatisflex.core.table.TableInfoFactory; import com.mybatisflex.core.table.TableManager; @@ -51,7 +52,12 @@ public class AccountSqlTester { .where(ACCOUNT01.ID.ge(100)) .and(ACCOUNT.SEX.eq(1)); - TableManager.setDynamicTableProcessor(original -> original+"_01"); + TableManager.setDynamicTableProcessor(new DynamicTableProcessor() { + @Override + public String process(String tableName) { + return tableName+"_01"; + } + }); TableManager.setDynamicTableProcessor(original -> original+"_01"); System.out.println(query.toDebugSQL());