mybatis 拦截器
有个需求需要对所有表新增一个字段resource_mark,来区分环境,但代码已经开发好,一个个添加麻烦,并且每个表都会有这个字段。
解决方法:mybatis拦截器
@Configuration
public class MyBatisConfig {
private final static Logger logger = LoggerFactory.getLogger(MyBatisConfig.class);
//设计到的表,在配置文件配置,为空则代表全部
@Value("${mybatis.rewrite.tables:''}")
private String rewriteTables;
@Autowired
private List<SqlSessionFactory> sqlSessionFactoryList;
@PostConstruct
public void addMySqlInterceptor() {
logger.info("=======================MyBatis Plugin=======================");
logger.info("=======================RewriteTables[{}]=======================",
rewriteTables.replace("|", ";"));
ResourceMarkInterceptor interceptor = new ResourceMarkInterceptor();
for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
// 添加自定义属性
interceptor.setProperties(new Properties() {
{
setProperty("resourceMarkTables", rewriteTables.replace("|", ";"));
setProperty("enableSaaS", "true");
setProperty("resourceMarkColumnName", "resource_mark");
setProperty("enableJoinSelect", "true");
setProperty("enableResourceMarkIsNull", "false");
}});
sqlSessionFactory.getConfiguration().addInterceptor(interceptor);
}
}
}
//mybatis拦截器拦截所有sql,修改我的的sql增加公用字段
@Intercepts({
@Signature(
type = StatementHandler.class,
method = "prepare",
args = {
Connection.class, Integer.class}
)})
public class ResourceMarkInterceptor implements Interceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(ResourceMarkInterceptor.class);
private RewriteSqlService rewriteSqlService = new RewriteSqlService();
private static final String PAGE_OFFSET = "OFFSET";
private static final String ENABLE_SAAS_PROPERTY = "enableSaaS";
private static final String ENABLE_RESOURCE_MARK_ISNULL = "enableResourceMarkNull";
private static final String ENABLE_JOIN_SELECT_PROPERTY = "enableJoinSelect";
private static final String RESOURCE_MARK_TABLES_PROPERTY = "resourceMarkTables";
private static final String RESOURCE_MARK_COLUMN_NAME = "resourceMarkColumnName";
private boolean enableSaaS = true;
private boolean enableResourceMarkNull = false;
public ResourceMarkInterceptor() {
}
private void process(StatementHandler handler) {
if (!this.isEnableSaaS()) {
LOGGER.debug("ResourceMarkInterceptor Interceptor skip ");
} else if (this.isEnableResourceMarkNull() && ResourceMarkInquirer.resourceMark == null) {
LOGGER.debug("ResourceMarkInterceptor Interceptor skip ");
} else {
MetaObject mo;
if (handler instanceof RoutingStatementHandler) {
mo = SystemMetaObject.forObject(handler);
this.process((StatementHandler) mo.getValue("delegate"));
} else {
mo = SystemMetaObject.forObject(handler);
BoundSql boundSql = (BoundSql) mo.getValue("boundSql");
String originalSql = boundSql.getSql();
String modifiedSql = this.rewriteSqlService.dispatch(originalSql);
modifiedSql = this.doPage(modifiedSql);
MetaObject boundSqlMo = SystemMetaObject.forObject(boundSql);
boundSqlMo.setValue("sql", modifiedSql);
}
}
}
private String doPage(String modifiedSql) {
return modifiedSql.contains(PAGE_OFFSET) ? modifiedSql.replace(PAGE_OFFSET, ",") : modifiedSql;
}
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler handler = (StatementHandler) invocation.getTarget();
this.process(handler);
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return target instanceof StatementHandler ? Plugin.wrap(target, this) : target;
}
@Override
public void setProperties(Properties properties) {
String enableSaaS = properties.getProperty(ENABLE_SAAS_PROPERTY, "true");
String enableResourceMarkIsNull = properties.getProperty(ENABLE_RESOURCE_MARK_ISNULL, "false");
String enableJoinSelect = properties.getProperty(ENABLE_JOIN_SELECT_PROPERTY, "false");
String tenantIdTables = properties.getProperty(RESOURCE_MARK_TABLES_PROPERTY);
String tenantIdColumnName = properties.getProperty(RESOURCE_MARK_COLUMN_NAME);
this.setEnableSaaS(Boolean.parseBoolean(enableSaaS));
this.setResourceMarkTables(tenantIdTables);
this.setEnableResourceMarkNull(Boolean.parseBoolean(enableResourceMarkIsNull));
this.rewriteSqlService.setTargetColumn(new ResourceMarkColumn(tenantIdColumnName));
this.rewriteSqlService.setEnableJoinSelect(Boolean.valueOf(enableJoinSelect));
this.rewriteSqlService.setEnableResourceMarkIsNull(Boolean.valueOf(enableResourceMarkIsNull));
}
public void setEnableSaaS(boolean enableSaaS) {
this.enableSaaS = enableSaaS;
}
public void setEnableResourceMarkNull(boolean enableResourceMarkNull) {
this.enableResourceMarkNull = enableResourceMarkNull;
}
public void