Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.baomidou.mybatisplus.extension.plugins.handler;

import com.baomidou.mybatisplus.core.toolkit.PluginUtils;

import java.util.Map;

/**
* 暴露MPBoundSql/BoundSql中的查询参数
*
* @author mika
* @since 3.5.13
*/
public class QueryParameterWrapper {
private Map<String, Object> queryParameterMap;
private QueryParameterWrapper(Map<String, Object> queryParameterMap) {
this.queryParameterMap = queryParameterMap;
}

public static QueryParameterWrapper createWrapper(PluginUtils.MPBoundSql mpBs) {
Object parameterObjs = mpBs.parameterObject();
if (parameterObjs instanceof Map) {
return new QueryParameterWrapper((Map<String, Object>)parameterObjs);
}
return null;
}

public Object getParameterValue(String key) {
if (queryParameterMap.containsKey(key)){
return queryParameterMap.get(key);
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.baomidou.mybatisplus.extension.plugins.handler;

/**
* 动态表名处理器Factory
*
* @author mika
* @since 3.5.13
*/
public interface TableNameHandlerFactory {
TableNameHandler createContextTableNameHandler(QueryParameterWrapper queryParameterWrapper);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.core.toolkit.TableNameParser;
import com.baomidou.mybatisplus.extension.plugins.handler.QueryParameterWrapper;
import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandlerFactory;
import lombok.Getter;
import lombok.Setter;
import org.apache.ibatis.executor.Executor;
Expand Down Expand Up @@ -53,8 +55,12 @@ public class DynamicTableNameInnerInterceptor implements InnerInterceptor {
/**
* 表名处理器,是否 处理表名的情况都在该处理器中自行判断
*/
@Deprecated
private TableNameHandler tableNameHandler = (sql, tableName) -> sql;

/**
* 表名处理器Factory,在实现中决定是静态处理, 还是每个handler都携带捕获到的BoundSql中的参数
*/
private TableNameHandlerFactory tableNameHandlerFactory = null;
/**
* 默认构建
*
Expand All @@ -65,15 +71,24 @@ public class DynamicTableNameInnerInterceptor implements InnerInterceptor {
public DynamicTableNameInnerInterceptor() {
}

@Deprecated
public DynamicTableNameInnerInterceptor(TableNameHandler tableNameHandler) {
this.tableNameHandler = tableNameHandler;
}

public DynamicTableNameInnerInterceptor(TableNameHandlerFactory tableNameHandlerFactory) {
this.tableNameHandlerFactory = tableNameHandlerFactory;
}

@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
if (InterceptorIgnoreHelper.willIgnoreDynamicTableName(ms.getId())) return;
PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
mpBs.sql(this.changeTable(mpBs.sql()));
//兼容直接使用类内静态tableNameHandler
TableNameHandler handler = tableNameHandlerFactory != null ?
tableNameHandlerFactory.createContextTableNameHandler(QueryParameterWrapper.createWrapper(mpBs))
: this.tableNameHandler;
mpBs.sql(this.changeTable(mpBs.sql(), handler));
}

@Override
Expand All @@ -86,13 +101,17 @@ public void beforePrepare(StatementHandler sh, Connection connection, Integer tr
return;
}
PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql();
mpBs.sql(this.changeTable(mpBs.sql()));
//兼容直接使用类内静态tableNameHandler
TableNameHandler handler = tableNameHandlerFactory != null ?
tableNameHandlerFactory.createContextTableNameHandler(QueryParameterWrapper.createWrapper(mpBs))
: this.tableNameHandler;
mpBs.sql(this.changeTable(mpBs.sql(), handler));
}
}

public String changeTable(String sql) {
public String changeTable(String sql, TableNameHandler handler) {
try {
return processTableName(sql);
return processTableName(sql, handler);
} finally {
if (hook != null) {
hook.run();
Expand All @@ -104,10 +123,11 @@ public String changeTable(String sql) {
* 处理表名解析替换
*
* @param sql 原始sql
* @param handler 表名处理器
* @return 处理完的sql
* @since 3.5.11
*/
protected String processTableName(String sql) {
protected String processTableName(String sql, TableNameHandler handler) {
TableNameParser parser = new TableNameParser(sql);
List<TableNameParser.SqlToken> names = new ArrayList<>();
parser.accept(names::add);
Expand All @@ -117,7 +137,7 @@ protected String processTableName(String sql) {
int start = name.getStart();
if (start != last) {
builder.append(sql, last, start);
builder.append(tableNameHandler.dynamicTableName(sql, name.getValue()));
builder.append(handler.dynamicTableName(sql, name.getValue()));
}
last = name.getEnd();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,26 +56,26 @@ public DynamicTableNameJsqlParserInnerInterceptor(TableNameHandler tableNameHand
}

@Override
protected String processTableName(String sql) {
protected String processTableName(String sql, TableNameHandler handler) {
boolean unsupported = false;
try {
Statement statement = JsqlParserGlobal.parse(sql);
statement.accept(new DynamicTableNameHandler(sql, super.getTableNameHandler()));
statement.accept(new DynamicTableNameHandler(sql, handler));
if (statement instanceof UnsupportedStatement) {
unsupported = true;
return super.processTableName(sql);
return super.processTableName(sql, handler);
}
return statement.toString();
} catch (Exception exception) {
return handleFallback(unsupported, sql, exception);
return handleFallback(unsupported, sql, handler, exception);
}
}

private String handleFallback(boolean unsupported, String sql, Exception originalException) {
private String handleFallback(boolean unsupported, String sql, TableNameHandler handler, Exception originalException) {
Exception exception = originalException;
if (!unsupported || shouldFallback) {
try {
return super.processTableName(sql);
return super.processTableName(sql, handler);
} catch (Exception e) {
exception = e;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.baomidou.mybatisplus.test.extension.plugins.inner;

import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import org.junit.jupiter.api.Test;

Expand All @@ -19,31 +20,32 @@ class DynamicTableNameInnerInterceptorTest {
@Test
@SuppressWarnings({"SqlDialectInspection", "SqlNoDataSourceInspection"})
void doIt() {
TableNameHandler handler = (sql, tableName) -> tableName + "_r";
DynamicTableNameInnerInterceptor interceptor = new DynamicTableNameInnerInterceptor();
interceptor.setTableNameHandler((sql, tableName) -> tableName + "_r");
interceptor.setTableNameHandler(handler);

// 表名相互包含
String origin = "SELECT * FROM t_user, t_user_role";
assertEquals("SELECT * FROM t_user_r, t_user_role_r", interceptor.changeTable(origin));
assertEquals("SELECT * FROM t_user_r, t_user_role_r", interceptor.changeTable(origin, handler));

// 表名在末尾
origin = "SELECT * FROM t_user";
assertEquals("SELECT * FROM t_user_r", interceptor.changeTable(origin));
assertEquals("SELECT * FROM t_user_r", interceptor.changeTable(origin, handler));

// 表名前后有注释
origin = "SELECT * FROM /**/t_user/* t_user */";
assertEquals("SELECT * FROM /**/t_user_r/* t_user */", interceptor.changeTable(origin));
assertEquals("SELECT * FROM /**/t_user_r/* t_user */", interceptor.changeTable(origin, handler));

// 值中带有表名
origin = "SELECT * FROM t_user WHERE name = 't_user'";
assertEquals("SELECT * FROM t_user_r WHERE name = 't_user'", interceptor.changeTable(origin));
assertEquals("SELECT * FROM t_user_r WHERE name = 't_user'", interceptor.changeTable(origin, handler));

// 别名被声明要替换
origin = "SELECT t_user.* FROM t_user_real t_user";
assertEquals("SELECT t_user.* FROM t_user_real_r t_user", interceptor.changeTable(origin));
assertEquals("SELECT t_user.* FROM t_user_real_r t_user", interceptor.changeTable(origin, handler));

// 别名被声明要替换
origin = "SELECT t.* FROM t_user_real t left join entity e on e.id = t.id";
assertEquals("SELECT t.* FROM t_user_real_r t left join entity_r e on e.id = t.id", interceptor.changeTable(origin));
assertEquals("SELECT t.* FROM t_user_real_r t left join entity_r e on e.id = t.id", interceptor.changeTable(origin, handler));
}
}
Loading