springboot~mybatis-plus的(de)DynamicTableNameInnerInterceptor實現分表(biao)
超輕量級
DynamicTableNameInnerInterceptor是(shi)mybatis-plug的(de)一個攔(lan)截器插(cha)件,可(ke)以自己定(ding)義需要攔(lan)截的(de)表(biao)單(dan),然(ran)后(hou)對它進行加工,這時mybatis-plus就(jiu)會把SQL代(dai)碼的(de)表(biao)名加上(shang)你的(de)這個裝飾(shi)。
封裝的思想
我們通常把mybatis做成一個包,公司其它同事直接使用咱們的包,包里會統一定義數據基類、數據分頁、數據脫敏、審(shen)計字段填充等(deng)特性,開(kai)發人員不需要(yao)關注這些內容(rong),這些內容(rong)會(hui)被自己注冊;或者人開(kai)發人員可(ke)以直接(jie)繼(ji)承它們,直接(jie)使用即可(ke)。
- 插件注冊器
@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;
}
.....
}
通過上面的(de)代碼我們知(zhi)道(dao),在外部(bu)定義的(de)DynamicTableNameInnerInterceptor對象,會被自動(dong)的(de)注(zhu)冊到mybatis-plus的(de)組(zu)件中,開(kai)發人員在具體(ti)項目里不(bu)需(xu)要(yao)再次(ci)注(zhu)冊。
- 開發人員在項目中定義一個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各版本對(dui)動態表(biao)名這塊支持都不一(yi)樣,很多方法和類在新版本中被(bei)刪除(chu)
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 ( ?, ?, ?, ?, ?, ?, ? )
需要注意的是(shi),無論(lun)是(shi)sharding-jdbc還(huan)是(shi)mybatis-plus-DynamicTableNameInnerInterceptor組成的分表,咱們都需要提前把(ba)數據表建立出來(lai),他們這(zhe)些組件是(shi)不會自動(dong)建表的。