MyBatis四大对象

mybatis四大对象指的是:executor,statementHandler,parameterHandler和resultHandler对象。这四个对象在sqlSession内部共同协作完成sql语句的执行,同时也是我们自定义插件拦截的四大对象。

1、 Executor

sqlSession 首先会调用executor.query方法执行查询。

Executor有以下四种(均继承了BaseExecutor,可在spring文件bean中配置):
SimpleExecutor-简单的Executor,所有的数据库操作均委托给StatementHandler处理
BatchExecutor - 批量更新的Executor,使用jdbc的batchupdate方法,使用此Executor,需要手动执行SqlSession的flushStatements,立即执行sql。
ReuseExecutor-大体上与SimpleExecutor相同,只是根据sql缓存了jdbc的statement,遇到相同的sql时,省去了statement的创建,提高效率,但需要手动执行SqlSession的flushStatements,清除缓存
CachingExecutor - 在mapper中配置cache,对查询结果做缓存,其中缓存的key根据以下代码存数生成,建议最好不要用mybatis这个层次的缓存,一般业务层的缓存更实用,而且更容易控制

mybatis生产Executor的关键代码如下:

public Object pluginAll(Object target) {  
    for (Interceptor interceptor : interceptors) {  
      target = interceptor.plugin(target);  
    }  
    return target;  
  }  

此处采用责任链与JDK动态代理模式结合的方式,遍历的Interceptor 即遍历mybatis的拦截器。责任链模式可理解为若干拦截器对象组成一条拦截链表,请求在这个拦截链表一直传递,直到链上的某一拦截器对象处理此请求,这一模式在servlet的Filter和Dubbo的Filter有用到。不同的是,mybatis责任链则是通过动态代理的方式,使用Plugin代理实际的Executor类,即plugin(plugin(…(executor)))。

public class Plugin implements InvocationHandler{
    private Object target;
    private Interceptor interceptor;
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {      
        if (满足代理条件) {
            return interceptor.intercept(new Invocation(target, method, args));
        }
        return method.invoke(target, args);     
    }

    //对传入的对象进行代理,可能是实际的Executor类,也可能是Plugin代理类
    public static Object wrap(Object target, Interceptor interceptor) {

        Class<?> type = target.getClass();
        Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
        if (interfaces.length > 0) {
            return Proxy.newProxyInstance(
                    type.getClassLoader(),
                    interfaces,
                    new Plugin(target, interceptor, signatureMap));
        }
        return target;
    }
} 

2、StatementHandler

Executor在doQuery时生成StatementHandler对象
在MyBatis实现了statementHandler的有四个类:
RoutingStatementHandler,这是一个封装类,它不提供具体的实现,只是根据Executor的类型,创建不同的类型StatementHandler。
SimpleStatementHandler,这个类对应于JDBC的Statement对象,用于没有预编译参数的SQL的运行。
PreparedStatementHandler 这个用于预编译参数SQL的运行。
CallableStatementHandler 它将实存储过程的调度。

statementHandler的主要方法:
prepare:编译sql
parameterize:prepare后设置参数
query/update:sql执行

基于StatementHandler对象定义的插件:
修改sql语句则在预编译SQL(prepare方法前)操作。
修改参数则在调用parameterize方法前修改逻辑。或者使用ParameterHandler来改造设置参数。
组装结果集则在query方法前后加入逻辑,或者使用ResultHandler来改造组装结果。

parameterHandler和resultHandler上述简单提到过,由于在mybatis自定义插件中也使用较少,这里不做详细阐述。
mybatis自定义插件的具体实现demo下一篇见
参考文章:https://blog.csdn.net/ykzhen2015/article/details/51690672
http://blue2048.iteye.com/blog/2173069
https://www.cnblogs.com/lizo/p/7503862.html

展开阅读全文

没有更多推荐了,返回首页