3.4.3.4
获取表名错误,动态替换当然也是错的
源代码通过Arrays.asList("table", "into", "join", "using", "update")确定表名,举例如果sql是“CREATE TABLE IF NOT EXISTS”,该方法会认为if是表名,所以请再多考虑各种sql的情况进行表名拆解。
public void accept(TableNameVisitor visitor) { int index = 0; String first = tokens.get(index).getValue(); if (isOracleSpecialDelete(first, tokens, index)) { visitNameToken(tokens.get(index + 1), visitor); } else if (isCreateIndex(first, tokens, index)) { visitNameToken(tokens.get(index + 4), visitor); } else { while (hasMoreTokens(tokens, index)) { String current = tokens.get(index++).getValue(); if (isFromToken(current)) { processFromToken(tokens, index, visitor); } else if (isOnDuplicateKeyUpdate(current, index)) { index = skipDuplicateKeyUpdateIndex(index); } else if (concerned.contains(current.toLowerCase())) { if (hasMoreTokens(tokens, index)) { SqlToken next = tokens.get(index++); visitNameToken(next, visitor); } } } } }
替换表名错误
Comment From: qmdx
命名规避冲突
Comment From: pangdangdang
命名规避冲突
CREATE TABLE IF NOT EXISTS t_cao_unservice_day_20211225 like t_cao_unservice_day ,请问是否明白这句sql的意思,表名是t_cao_unservice_day_20211225 ,什么叫做命名规避冲突,你是认为if是表名吗,根据关键词table", "into", "join", "using", "update后面衔接的字符串认为是表名,这不是有bug吗
Comment From: qmdx
CREATE TABLE IF NOT EXISTS t_cao_unservice_day_20211225 like t_cao_unservice_day ,请问是否明白这句sql的意思,表名是t_cao_unservice_day_20211225 ,什么叫做命名规避冲突,你是认为if是表名吗,根据关键词table", "into", "join", "using", "update后面衔接的字符串认为是表名,这不是有bug吗
当前解析工具类 com.baomidou.mybatisplus.core.toolkit.TableNameParser 不支持创表语句。
请给出你的完整 sql
Comment From: pangdangdang
CREATE TABLE IF NOT EXISTS t_cao_unservice_day_20211225 like t_cao_unservice_day ,请问是否明白这句sql的意思,表名是t_cao_unservice_day_20211225 ,什么叫做命名规避冲突,你是认为if是表名吗,根据关键词table", "into", "join", "using", "update后面衔接的字符串认为是表名,这不是有bug吗
当前解析工具类 com.baomidou.mybatisplus.core.toolkit.TableNameParser 不支持创表语句。
请给出你的完整 sql
这就是完整语句,创建删除表不支持的话,应该在你们的拦截器提供过滤,目前看到源码中可以根据配置的表名不进行拦截替换,但是实际上常用的功能是对于表的某些语句方法不要拦截替换,不然拦截又报错使用方该怎么办
Comment From: qmdx
这种 sql 你应该可以自己控制表名的,插件排除执行方法即可
Comment From: pangdangdang
这种 sql 你应该可以自己控制表名的,插件排除执行方法即可 你们动态表名得拦截器没有对某些方法过滤,插件怎么排除执行方法呢 /* * 表名处理器,是否处理表名的情况都在该处理器中自行判断 / private TableNameHandler tableNameHandler;
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
if (InterceptorIgnoreHelper.willIgnoreDynamicTableName(ms.getId())) return;
mpBs.sql(this.changeTable(mpBs.sql()));
}
@Override
public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {
PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh);
MappedStatement ms = mpSh.mappedStatement();
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()));
}
}
protected String changeTable(String sql) {
ExceptionUtils.throwMpe(null == tableNameHandler, "Please implement TableNameHandler processing logic");
TableNameParser parser = new TableNameParser(sql);
List<TableNameParser.SqlToken> names = new ArrayList<>();
parser.accept(names::add);
StringBuilder builder = new StringBuilder();
int last = 0;
for (TableNameParser.SqlToken name : names) {
int start = name.getStart();
if (start != last) {
builder.append(sql, last, start);
builder.append(tableNameHandler.dynamicTableName(sql, name.getValue()));
}
last = name.getEnd();
}
if (last != sql.length()) {
builder.append(sql.substring(last));
}
return builder.toString();
}
Comment From: qmdx
https://baomidou.com/pages/223848/#interceptorignore