# MyBatis Plus 动态表名 **Repository Path**: ding123123/dynamictable ## Basic Information - **Project Name**: MyBatis Plus 动态表名 - **Description**: 基于MyBatis Plus的更加强大的动态表名功能 - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 5 - **Created**: 2022-07-18 - **Last Updated**: 2022-07-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 动态表名生成器 从3.4.0 版本开始,MyBatis Plus 实现了基本的 **动态表名** 功能,但局限性比较大,没有办法使用外部参数去指定生成表名的规则, 本项目则实现了一个更加强大的动态表名功能。 MyBatis Plus 动态表名的原理就是sql替换。 比如有这样一条SQL ```sql UPDATE TABLE T_USER SET real_name = "张三" where role = "admin" ``` 如果指定生成表名的规则是**原始表名_系统时间**,那么系统会解析sql语句,找到原始表的表名**T_USER**, 然后获取系统时间,那么动态表名执行后的sql语句就变成了 ```sql UPDATE TABLE T_USER_202101229 SET real_name = "张三" where role = "admin" ``` 其中的**T_USER**被替换成了**T_USER_202101229**,这就是动态表名的原理 当然如果生成表名的规则不需要手动传入其他参数,如只使用当前系统的日期来生成新的表名,那么只使用MyBatis Plus官方的动态表名即可 官方教程入口:[https://baomidou.com/guide/interceptor-dynamic-table-name.html#dynamictablenameinnerinterceptor](https://baomidou.com/guide/interceptor-dynamic-table-name.html#dynamictablenameinnerinterceptor) ## 环境 * Java 8 * Maven 3.5.4 * MyBatis Plus 3.4.1 ## 示例 ##### 基本配置 ```java @MapperScan("baiqitun.dynamicdemo.mapper") @Slf4j @Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); MyDynamicTableNameInnerInterceptor myDynamicTableNameInnerInterceptor = new MyDynamicTableNameInnerInterceptor(); // map的key就是原始表名,value就是表名替换规则 HashMap map = new HashMap(2) {{ //整个函数返回的结果就是替换后的新表名,这个生成的表名的规则可以自己随便指定 put("T_USER", (sql, tableName, user) -> tableName + user.departCode); //上面的是lambda表达式,等价于下面的代码 put("T_USER", new MyTableNameHandler(){ public String dynamicTableName(String sql, String tableName, Object depart){ if (user.getDepartCode() == null){ throw new RuntimeException("User必须指定‘DepartCode’字段"); } // T_USER表生成规则是[T_USER_用户所属部门编码] return tableName + user.getDepartCode().toUpperCase(); } }); }}; // 上面的代码实现了只对T_USER表生成新表 myDynamicTableNameInnerInterceptor.setTableNameHandlerMap(map); interceptor.addInnerInterceptor(myDynamicTableNameInnerInterceptor); return interceptor; } } ``` 具体使用的方式与官方文档一致,建议没有学习过MyBatis Plus代码生成器的清先移步MyBatis Plus官网学习代码生成器的使用 *** 1. 保存 下面的代码就将user保存到了**T_USER_DEVELOP**表 ```java TUser user = new TUser(); user.setUsername("admin"); user.setPassword("123"); user.setDepartCode("DEVELOP"); userServer.save(user); ``` 2. 查询**T_USER_MAIN**表的所有数据 ```java TUser queryUser = new TUser(); queryUser.setDepartCode("MAIN"); List users = userService.list(new QueryWrapper(queryUser)); ``` ##### 指定通用规则 所有表都适用的生成动态表名的规则 ```java @Import(cn.hutool.extra.spring.SpringUtil.class) @MapperScan("baiqitun.dynamictable.mapper") @Slf4j @Configuration public class MybatisPlusConfig { @Autowired private SpringUtil springUtil; @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); // 取消MyBatis Plus的最大分页500条的限制 paginationInnerInterceptor.setMaxLimit(100000L); MyDynamicTableNameInterceptor myDynamicTableNameInterceptor = new MyDynamicTableNameInterceptor(); HashMap map = new HashMap(2) {{ //整个函数返回的结果就是替换后的新表名,这个生成的表名的规则可以自己随便指定 put("test_student", (sql, tableName, student) -> tableName + "_" +((SysStudent)student).getDepartCode()); }}; DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor(); myDynamicTableNameInterceptor.setTableNameHandlerMap(map); interceptor.addInnerInterceptor(myDynamicTableNameInterceptor); interceptor.addInnerInterceptor(paginationInnerInterceptor); return interceptor; } } ``` 注意! **MyDynamicTableNameInnerInterceptor** 只负责生成动态表名,而不会动态创建表! 如果有动态创建表的需求有如下两种方式 1. 手动创建 2. 自己实现动态创建表的代码