当前位置 主页 > 网站技术 > 代码类 >

    MyBatis执行Sql的流程实例解析(3)

    栏目:代码类 时间:2019-12-23 21:08

    然后,通过一层一层的调用,最终会来到doQuery方法, 这儿咱们就随便找个Excutor看看doQuery方法的实现吧,我这儿选择了SimpleExecutor:

    public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
      Statement stmt = null;
      try {
       Configuration configuration = ms.getConfiguration();
       //内部封装了ParameterHandler和ResultSetHandler
       StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
       stmt = prepareStatement(handler, ms.getStatementLog());
       //StatementHandler封装了Statement, 让 StatementHandler 去处理
       return handler.<E>query(stmt, resultHandler);
      } finally {
       closeStatement(stmt);
      }
     }

    接下来,咱们看看StatementHandler 的一个实现类 PreparedStatementHandler(这也是我们最常用的,封装的是PreparedStatement), 看看它使怎么去处理的:

    public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
       //到此,原形毕露, PreparedStatement, 这个大家都已经滚瓜烂熟了吧
      PreparedStatement ps = (PreparedStatement) statement;
      ps.execute();
      //结果交给了ResultSetHandler 去处理,处理完之后返回给客户端
      return resultSetHandler.<E> handleResultSets(ps);
     }

    到此,整个调用流程结束。

    简单总结

    这边结合获取SqlSession的流程,做下简单的总结:

    SqlSessionFactoryBuilder解析配置文件,包括属性配置、别名配置、拦截器配置、环境(数据源和事务管理器)、Mapper配置等;解析完这些配置后会生成一个Configration对象,这个对象中包含了MyBatis需要的所有配置,然后会用这个Configration对象创建一个SqlSessionFactory对象,这个对象中包含了Configration对象; 拿到SqlSessionFactory对象后,会调用SqlSessionFactory的openSesison方法,这个方法会创建一个Sql执行器(Executor组件中包含了Transaction对象),这个Sql执行器会代理你配置的拦截器方法。 获得上面的Sql执行器后,会创建一个SqlSession(默认使用DefaultSqlSession),这个SqlSession中也包含了Configration对象和上面创建的Executor对象,所以通过SqlSession也能拿到全局配置; 获得SqlSession对象后就能执行各种CRUD方法了。

    以上是获得SqlSession的流程,下面总结下本博客中介绍的Sql的执行流程:

    调用SqlSession的getMapper方法,获得Mapper接口的动态代理对象MapperProxy,调用Mapper接口的所有方法都会调用到MapperProxy的invoke方法(动态代理机制); MapperProxy的invoke方法中唯一做的就是创建一个MapperMethod对象,然后调用这个对象的execute方法,sqlSession会作为execute方法的入参; 往下,层层调下来会进入Executor组件(如果配置插件会对Executor进行动态代理)的query方法,这个方法中会创建一个StatementHandler对象,这个对象中同时会封装ParameterHandler和ResultSetHandler对象。调用StatementHandler预编译参数以及设置参数值,使用ParameterHandler来给sql设置参数。

    Executor组件有两个直接实现类,分别是BaseExecutor和CachingExecutor。CachingExecutor静态代理了BaseExecutor。Executor组件封装了Transction组件,Transction组件中又分装了Datasource组件。

    调用StatementHandler的增删改查方法获得结果,ResultSetHandler对结果进行封装转换,请求结束。