系统数据隔离|根据mybatis 拦截器实现项目业务数据隔离

package com.wangzhixuan.commons.intercept;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.util.Properties;
【系统数据隔离|根据mybatis 拦截器实现项目业务数据隔离】import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.wangzhixuan.commons.sqlparser.SelectVisitorImpl;
import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.statement.select.Select;
@Intercepts({
@Signature(method = “prepare”, type = StatementHandler.class, args = { Connection.class, Integer.class})
})
public class TestInterceptor implements Interceptor {
// 控制器本来就是单例,这样似乎更加合理
protected Logger logger = LogManager.getLogger(getClass());

private CCJSqlParserManager parserManager = new CCJSqlParserManager(); @Override public Object intercept(Invocation invocation) throws InvocationTargetException, IllegalAccessException { if(invocation.getTarget() instanceof StatementHandler) { //逻辑代码区 StatementHandler statementHandler = (StatementHandler)invocation.getTarget(); MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler); // 分离代理对象链(由于目标类可能被多个拦截器拦截,从而形成多次代理,通过下面的两次循环 // 可以分离出最原始的的目标类) while (metaStatementHandler.hasGetter("h")) { Object object = metaStatementHandler.getValue("h"); metaStatementHandler = SystemMetaObject.forObject(object); } // 分离最后一个代理对象的目标类 while (metaStatementHandler.hasGetter("target")) { Object object = metaStatementHandler.getValue("target"); metaStatementHandler = SystemMetaObject.forObject(object); } MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement"); //获取sql BoundSql boundSql = statementHandler.getBoundSql(); String sql = boundSql.getSql(); if(sql.contains("NEXTVAL")){ // 去掉子序列函数 return invocation.proceed(); } //获取方法id String id = mappedStatement.getId(); if (id.contains("InventoryInoutMapper") || id.contains("selectSaleReportByGmtCreate") || id.contains("selectBiShipReportByGmtCreate") || id.contains("selectTransNoinventoryReport") || id.contains("queryPurStoDetails") || id.contains("queryTaskDailyCloseIds")) { // 剔除不需要走拦截器的方法 return invocation.proceed(); } //获得方法类型 SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType(); if ("SELECT".equals(sqlCommandType.toString())) { //如果是select就将sql转成SELECT对象 try { Select select = (Select)parserManager.parse(new StringReader(sql)); //访问各个visitor select.getSelectBody().accept(new SelectVisitorImpl()); //将增强后的sql放回 metaStatementHandler.setValue("delegate.boundSql.sql", select.toString()); return invocation.proceed(); } catch(Throwable e) { logger.error("拦截器异常Start"); logger.error(e); logger.error("拦截器异常End"); } } } return invocation.proceed(); }@Override public Object plugin(Object target) { //生成代理对象 return Plugin.wrap(target, this); }@Override public void setProperties(Properties properties) { }

}

    推荐阅读