mybatis的一个分库分表插件--jade

通过@Intercepts注解信息和@Signature注解信息可以了解到,JadeSQLInterceptor会拦截Executor.query(MappedStatement, Object, RowBounds, ResultHandler)和Executor.update(MappedStatement, Object)两个方法

@Intercepts({
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
                RowBounds.class, ResultHandler.class}),
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class JadeSQLInterceptor implements Interceptor {
    // ......
}

介绍完注解信息后,再来看看plugin()方法,具体实现如下:

    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
其中会解析JadeSQLInterceptor中的@Intercepts和@Signature注解的信息,从而确定需要拦截的方法,然后使用JDK动态代理的方式,为JadeSQLInterceptor创建代理对象。在该代理对象中,会拦截Executor.query(MappedStatement, Object, RowBounds, ResultHandler)和Executor.update(MappedStatement, Object),拦截的具体逻辑在JadeSQLInterceptor.intercept()方法中实现的,具体

    1 从调用者信息invocation中获取method信息,然后判断method是否有ShardBy注解,获取shard的param,

    2 根据这个param分表策略重写sql,再将重写后的sql设置到method的arg[1]中,

    3 调用target object的method方法执行后续操作

  public Object intercept(Invocation invocation) throws Throwable {
        //获取被拦截方法的参数列表  
        Object[] args = invocation.getArgs();
        MappedStatement statement = (MappedStatement) args[INDEX_MAPPED_STATEMENT];
        //获取dao类  
        Class dao = mapperClazz(statement);
        //获取dao中执行的method 
        Method method = shardMapperMethod(statement, dao); 
        // 在这里判断dao的method中是否有ShardBy注解,如果有,表明需要分表操作。返回ShardBy注解的Param,后面会用到  
        Object shardByObject = getExecuteParamByAnnotationClass(args, method, ShardBy.class);
        Modifier modifier = new Modifier(new Definition(dao), method);
        BoundSql boundSql = statement.getBoundSql(args[INDEX_PARAMETER]);
        // 如果需要分表则在这里进行分表分析  
        if (shardByObject != null) {

            Configuration configuration = statement.getConfiguration();
            // 获取dataSource,这个dataSource是spring的代理dataSource  
            DataSource dataSource = configuration.getEnvironment() != null ? configuration.getEnvironment().getDataSource() : null;
            //获取method中标有Param注解的信息  
            Map<String, Object> params = getJadeParameters(args, method);
            RouterInterpreter interpreter = BeanFactory.getBean("jade.routerInterpreter", RouterInterpreter.class);
            //设置到线程变量中,后面解析sql时会用到
            SQLThreadLocal.set(getSQLType(statement), boundSql.getSql(), modifier, params); 
            // 路由了数据源,且重写了sql语句  
            SQLInterpreterResult result =
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值