从上述的代码中我们可以看到SqlSession的职能是:
SqlSession根据Statement ID, 在mybatis配置对象Configuration中获取到对应的MappedStatement对象,然后调用mybatis执行器来执行具体的操作。
进入BaseExecutor 的queryFromDatabase方法:
然后进入SimpleExecutor的doQuery方法:
进入StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, rowBounds, resultHandler, boundSql);看下newStatementHandler到底干了些什么事情?
进入RoutingStatementHandler类看下构造方法:
根据MappedStatement对象的StatementType来创建不同的StatementHandler,这个跟前面的执行器类似。StatementType有STATEMENT、PREPARED和CALLABLE三种类型,跟JDBC里面的Statement类型一一对应。
进入InterceptorChain类的pluginAll类看下方法:
下面是自己实现了一个分页如下:
接着上面的plugin方法,然后进入Plugin类,可以看到是JDK动态代理实现的类,里面的wrap方式生成一个代理对象的方法,通过目标对象taget=PreparedStatementHandler以及上面部分的注解StatementHandler 接口动态的生成代理对象。然后在执行invoke方法的时候,再次检测
部分注解信息中的method = "prepare"方法,如果存在要拦截的方法,则执行PaginationInterceptor中的intercept方法做拦截处理,加上分页条件等。然后才执行prepare方法。
接口如下:
上述的Executor.query()方法几经转折,最后会创建一个StatementHandler对象,然后将必要的参数传递给StatementHandler,使用StatementHandler来完成对的查询,最终返回List结果集。
从上面的代码中我们可以看出,Executor的功能和作用是:
(1、根据传递的参数,完成SQL语句的动态解析,生成BoundSql对象,供StatementHandler使用;
(2、为查询创建缓存,以提高性能;
(3、创建JDBC的Statement连接对象,传递给StatementHandler对象,返回List查询结果。
接着上面的Executor第六步,看一下:prepareStatement()方法的实现:
以上我们可以总结StatementHandler对象主要完成两个工作:
(1. 对于JDBC的PreparedStatement类型的对象,创建的过程中,我们使用的是SQL语句字符串会包含 若干个? 占位符,我们其后再对占位符进行设值。
StatementHandler通过parameterize(statement)方法对Statement进行设值;
(2.StatementHandler通过List<E> query(Statement statement, ResultHandler resultHandler)方法来完成执行Statement,和将Statement对象返回的resultSet封装成List;
从上述的代码可以看到,StatementHandler 的parameterize(Statement) 方法调用了 ParameterHandler的setParameters(statement) 方法,
ParameterHandler的setParameters(Statement)方法负责 根据我们输入的参数,对statement对象的 ? 占位符处进行赋值。
从上述代码我们可以看出,StatementHandler的List<E> query(Statement statement, ResultHandler resultHandler)方法的实现,是调用了ResultSetHandler的handleResultSets(Statement)方法。ResultSetHandler的handleResultSets(Statement)方将Statement语句执行后生成的resultSet结果集转换成List<E>结果集。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/tongxinshuyu/article-40255-4.html
不行就是不行