5

springboot~mybatis-plus的DynamicTableNameInnerInterceptor实现分表

 1 year ago
source link: https://www.cnblogs.com/lori/p/17428147.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

DynamicTableNameInnerInterceptor是mybatis-plug的一个拦截器插件,可以自己定义需要拦截的表单,然后对它进行加工,这时mybatis-plus就会把SQL代码的表名加上你的这个装饰。

封装的思想

我们通常把mybatis做成一个包,公司其它同事直接使用咱们的包,包里会统一定义数据基类数据分页数据脱敏、审计字段填充等特性,开发人员不需要关注这些内容,这些内容会被自己注册;或者人开发人员可以直接继承它们,直接使用即可。

  • 插件注册器
@Configuration
public class MybatisPlusConfig implements ApplicationContextAware {

	ApplicationContext applicationContext;

	/**
	 * 拦截器
	 */
	@Bean
	public MybatisPlusInterceptor mybatisPlusInterceptor() {
		MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
		// 分页插件, 对于单一数据库类型来说,都建议配置该值,避免每次分页都去抓取数据库类型
		interceptor.addInnerInterceptor(new LindPaginationInnerInterceptor());
		// 防止全表更新与删除
		interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
		// 加载个性化的分表配置,它可能是用户在当前项目定义的,然后我们统一对它们进行装配
		Optional.ofNullable(applicationContext.getBeanNamesForType(DynamicTableNameInnerInterceptor.class))
				.ifPresent(o -> {
					for (String beanName : o) {
						DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = applicationContext
								.getBean(beanName, DynamicTableNameInnerInterceptor.class);
						interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
					}
				});
		return interceptor;
	}
.....
}

通过上面的代码我们知道,在外部定义的DynamicTableNameInnerInterceptor对象,会被自动的注册到mybatis-plus的组件中,开发人员在具体项目里不需要再次注册。

  • 开发人员在项目中定义一个t_log表,按时间进行分表
	@Bean
	public DynamicTableNameInnerInterceptor tableNamePlusInterceptor() {
		DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
		HashMap<String, TableNameHandler> map = new HashMap<String, TableNameHandler>();

		map.put("t_log", new DaysTableNameParser());

		dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map);
		return dynamicTableNameInnerInterceptor;
	}

所依赖的版本

mybatis-plus各版本对动态表名这块支持都不一样,很多方法和类在新版本中被删除

com.baomidou:mybatis-plus-boot-starter:3.4.3

代码的测试

	@Test(expected = BadSqlGrammarException.class)
	public void insertLog() {
		TLog log = new TLog();
		log.setMessage("测试");
		logDao.insert(log);
	}

生成的sql代码如下

[main] DEBUG com.lind.mybatis.dao.LogDao.insert - ==>  Preparing: INSERT INTO t_log_20230524 ( id, message, create_by, create_time, update_by, update_time, del_flag ) VALUES ( ?, ?, ?, ?, ?, ?, ? )

需要注意的是,无论是sharding-jdbc还是mybatis-plus-DynamicTableNameInnerInterceptor组成的分表,咱们都需要提前把数据表建立出来,他们这些组件是不会自动建表的。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK