Mybatis核心对象及插件使用

1,核心对象


Configuration: mybatis的核心配置类,里面维护了mybatis的各种属性。

Sqlsession: 一个会话,里面定义了各种操作数据库的方法,和应用层交互。

Executor: Mybatis执行器,负责生成Sql和查询缓存。

StatementHanler: 负责对JDBC Statement的操作,例如设置参数。

ParameterHandler: 负责将用户参数转换为JDBC Statement需要的参数。

ResultSetHandler: 负责数据库返回的对象转化为Java需要的。

MapperProxy: mapper接口的代理对象。

MapperStatement: 对一个(select|update|delete|insert)节点的封装,里面包含了sql语句,出参,入参等一些参数。

2,插件原理与自定义插件


如果我们想对原代码进行功能上的增强,那么我想到代理模式,mybatis中只有四个对象允许被代理拦截,Executor,StatementHanler,ParameterHandler,ResultSetHandler

2.1,以PageHelpher为例,分析开发插件的流程


2.1.1,实现Interceptor接口,在上面加上@Intercepts注解,指定拦截的类和方法(方法名称和参数类型构成了一个方法的签名),实现接口的三个方法。
            intercept():覆盖被拦截对象的原有的方法
            plugin():给被拦截对象生成一个代理对象。


2.1.2,在mybatis-config.xml中注册插件

2.2.3,登记插件

    mybatis启动时,扫描<plugin>标签,注册到了Configuration对象中的InterceptorChain中,property里面的参数会调用setProperties方法处理。

3.1,代理和拦截的实现


3.1.1,四大对象什么时候被代理的?

    Executor在openSession的时候,另外三个在SimpleExecutor调用doQuery的时候创建的。然后使用interceptorChain.pluginAll返回层层代理的对象。
    statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
    parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
    resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
    executor = (Executor) interceptorChain.pluginAll(executor);

3.1.2,多个插件的情况下,代理能不能被代理,代理顺序和调用顺序的关系?

    代理可以被代理,代理顺序是从内到外,调用顺序是从外到内。

3.1.3,谁来创建代理对象?

    Plugin类,Plugin.wrap方法返回代理对象

3.1.4,被代理后,调用的是什么方法?怎么调用到原来被代理对象的方法?
    
    举例Executor被自己写的一个拦截器(MyInterceptor)拦截
    第一步:target = interceptor.plugin(target); MyInterceptor会调用Plugin.wrap返回一个代理对象。
    第二步:当执行Executor的具体的方法的时候,其实执行的是Plugin中的invoke方法,里面用Invocation对被代理对象进行了封装。 return interceptor.intercept(new Invocation(target, method, args));
    第三步:调用MyInterceptor中的intercept方法,接着进行我们的处理,最后我们可以调用Invocation中的process方法,执行原来对象的方法。
    public Object proceed() throws InvocationTargetException, IllegalAccessException {
        return method.invoke(target, args);
    }

3.2,应用场景分析

    水平分表:对query方法进行拦截,在接口上添加注解,获取注解上的参数进行分表,修改原Sql,例如id取模,按月分表
    数据加解密:query解密,update加密。
    菜单权限控制:对query方法拦截,获取方法上面的注解,根据权限配置以及用户登录信息,在Sql上加上权限过滤条件。





posted @ 2020-05-15 14:34  gnice512  阅读(321)  评论(0编辑  收藏  举报