MyBatis-Plus 官方提供「动态表名插件」
参考官方文档:https://baomidou.com/pages/2a45ff/#dynamictablenameinnerinterceptor
但压测下来,通过火焰图分析,此插件比较消耗CPU,对性能产生了一定的影响。
1 2 3 4 5 6 7 8 9 10 11 12
| @Bean @Override public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
Map<String, TableNameHandler> tableNameHandlers = Maps.newHashMap(); tableNameHandlers.put("foobars", (sql, tableName) -> tableName + DateFormatUtils.format(new Date(), "yyyyMMdd")); DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor(tableNameHandlers); interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor); return interceptor; }
|
以上代码(只是样例)为默认动态表名插件的配置,即访问 foobars
表会,会自动替换成 foobars_当前日期
表名。
如果为写此博客的日期,表名则为 foobars_20230721
。
通过源码分析不难发现,每个SQL(无论是否包含动态表名的SQL)都需要解析SQL!!!
如果项目中大部分表不是动态表名的,那就非常得不偿失了。
带来的性能影响 远远大于 带来的收益。
优化后的「动态表名插件」
动态表名插件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| public class MyDynamicTableNameInnerInterceptor extends DynamicTableNameInnerInterceptor {
private final Set<String> mapperClassNames = Sets.newHashSet();
public MyDynamicTableNameInnerInterceptor() { setTableNameHandlerMap(Maps.newHashMap()); }
public void addDynamicTable(String tableName, Class<? extends Mapper<?>> mapper, TableNameHandler tableNameHandler) { mapperClassNames.add(mapper.getName()); getTableNameHandlerMap().put(tableName, tableNameHandler); }
@Override public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { for (String mapperClassName : mapperClassNames) { if (ms.getId().startsWith(mapperClassName)) { super.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql); break; } } }
@Override public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) { PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh); MappedStatement ms = mpSh.mappedStatement(); for (String mapperClassName : mapperClassNames) { if (ms.getId().startsWith(mapperClassName)) { SqlCommandType sct = ms.getSqlCommandType(); if (sct == SqlCommandType.INSERT || sct == SqlCommandType.UPDATE || sct == SqlCommandType.DELETE) { if (InterceptorIgnoreHelper.willIgnoreDynamicTableName(ms.getId())) return; PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql(); mpBs.sql(this.changeTable(mpBs.sql())); } break; } } }
}
|
Bean配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Bean @Override public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = super.mybatisPlusInterceptor();
MyDynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new MyDynamicTableNameInnerInterceptor(); dynamicTableNameInnerInterceptor.addDynamicTable( "foobars", FoobarMapper.class, (sql, tableName) -> tableName + DateFormatUtils.format(new Date(), "yyyyMMdd") ); interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
return interceptor; }
|
可减少大量的SQL解析!!!