mybatis攔截器實現資料庫表水平切分
阿新 • • 發佈:2019-01-29
攔截器主要的作用是讀取配置,根據配置的切分策略和欄位,來切分表,然後替換原執行的SQL,從而實現自動切分,上程式碼:
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) }) public class TableSegInterceptor implements Interceptor { private static final String tag = TableSegInterceptor.class.getName(); private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory(); private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory(); @Override public Object intercept(Invocation invocation) throws Throwable { StatementHandler statementHandler = (StatementHandler) invocation .getTarget(); MetaObject metaStatementHandler = MetaObject.forObject( statementHandler, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY); String originalSql = (String) metaStatementHandler .getValue("delegate.boundSql.sql"); BoundSql boundSql = (BoundSql) metaStatementHandler .getValue("delegate.boundSql"); //Configuration configuration = (Configuration) metaStatementHandler //.getValue("delegate.configuration"); Object parameterObject = metaStatementHandler .getValue("delegate.boundSql.parameterObject"); if (originalSql!=null&&!originalSql.equals("")) { MappedStatement mappedStatement = (MappedStatement) metaStatementHandler .getValue("delegate.mappedStatement"); String id = mappedStatement.getId(); String className = id.substring(0, id.lastIndexOf(".")); Class<?> classObj = Class.forName(className); //根據配置自動生成分表SQL TableSeg tableSeg = classObj.getAnnotation(TableSeg.class); if(tableSeg!=null){ AnalyzeActualSql as = new AnalyzeActualSqlImpl(mappedStatement, parameterObject, boundSql); String newSql=as.getActualSql(originalSql, tableSeg); if(newSql!=null){ LogUtil.d(tag,"分表後SQL =====>"+ newSql); metaStatementHandler.setValue("delegate.boundSql.sql", newSql); } } } // 傳遞給下一個攔截器處理 return invocation.proceed(); } @Override public Object plugin(Object target) { // 當目標類是StatementHandler型別時,才包裝目標類,否者直接返回目標本身,減少目標被代理的 // 次數 if (target instanceof StatementHandler) { return Plugin.wrap(target, this); } else { return target; } } @Override public void setProperties(Properties properties) { // TODO Auto-generated method stub }