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