Interceptor 1 :
@Intercepts(
{
@Signature(
type = Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
),
@Signature(
type = Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}
)
}
)
public class SelectLimitInterceptor implements Interceptor {
public SelectLimitInterceptor() {
}
@Override
public Object intercept(Invocation invocation) throws Throwable {
DataSourceType dataSource = DataSourceContextHolder.getDataSource();
Object[] args = invocation.getArgs();
MappedStatement ms = (MappedStatement)args[0];
Object parameter = args[1];
RowBounds rowBounds = (RowBounds) args[2];
ResultHandler resultHandler = (ResultHandler) args[3];
Executor executor = (Executor)invocation.getTarget();
CacheKey cacheKey;
BoundSql boundSql;
if (args.length == 4) {
boundSql = ms.getBoundSql(parameter);
cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);
} else {
cacheKey = (CacheKey) args[4];
boundSql = (BoundSql) args[5];
}
String sql = boundSql.getSql();
if (DataSourceEnum.TIMESTEN.equals(dataSource)){
sql = "Select * from (" + sql + ") t where rownum < 10000";
} else {
sql = "Select * from (" + sql + ") t limit 10000";
}
ReflectUtil.setFieldValue(boundSql, "sql", sql);
return executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql);
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
}
Interceptor 2 : 给默认字段赋值
@Intercepts(
{
@Signature(
type = Executor.class,
method = "update",
args = {MappedStatement.class, Object.class}
)
}
)
public class FieldInterceptor implements Interceptor {
public FieldInterceptor() {
}
@Override
public Object intercept(Invocation invocation) throws Throwable {
try {
Object parameter = invocation.getArgs()[1];
MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
SqlCommandType sqlCommandType = ms.getSqlCommandType();
if (parameter instanceof MapperMethod.ParamMap) {
MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap)parameter;
final int size = paramMap.size();
for (int i = 0; i < size/2; ++i) {
this.checkAndSet(paramMap.get("param"+ i), sqlCommandType);
}
} else if (parameter instanceof DefaultSqlSession.StrictMap) {
List collection = (List)((DefaultSqlSession.StrictMap)parameter).get("collection");
Iterator iterator = collection.iterator();
while (iterator.hasNext()) {
Object obj = iterator.next();
this.checkAndSet(obj, sqlCommandType);
}
} else {
this.checkAndSet(parameter, sqlCommandType);
}
}catch (Exception e){
//log
}
return invocation.proceed();
}
private void checkAndSet(Object parameter, SqlCommandType sqlCommandType){
if (parameter instanceof BaseDTO && (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType))){
String currentName = "SYSTEM";
BaseDTO baseDTO = (BaseDTO)parameter;
if (StringUtils.isEmpty(baseDTO.getUpdateBy())){
baseDTO.setUpdateBy(currentName);
}
if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)){
baseDTO.setCreateBy(currentName);
}
if (parameter instanceof List) {
Iterator it = ((List<?>) parameter).iterator();
while (it.hasNext()) {
Object obj = it.next();
this.checkAndSet(obj, sqlCommandType);
}
}
}
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
}
将Interceptor使用Spring容器管理:
@Configuration
public class MybatisConfig {
@Bean
public FieldInterceptor fieldInterceptor(){
FieldInterceptor interceptor = new FieldInterceptor();
Properties prop = new Properties();
prop.put("dialect", "mysql");
interceptor.setProperties(prop);
return interceptor;
}
@Bean
public SelectLimitInterceptor selectLimitInterceptor(){
SelectLimitInterceptor interceptor = new SelectLimitInterceptor();
Properties prop = new Properties();
prop.put("dialect", "mysql");
interceptor.setProperties(prop);
return interceptor;
}
@Bean(name = "dataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
List<Filter> filters = new ArrayList<>();
filters.add(wallFilter);
dataSource.setProxyFilters(filters);
return dataSource;
}
@Bean(name = "wallFilter")
@DependsOn("wallConfig")
public WallFilter wallFilter(){
WallFilter interceptor = new WallFilter();
interceptor.setConfig(wallConfig());
return interceptor;
}
@Bean(name = "wallConfig")
public WallConfig wallConfig(){
WallConfig wallConfig = new WallConfig();
wallConfig.setMultiStatementAllow(true);
return wallConfig;
}
}
上面设置filters的地方有点问题,路过的大佬,可以提点建议;