Mybatis(14)-Mybatis运行原理04


执行增删改查方法

        进入invoke方法,调用execute方法。

        execute()方法中根据SQL类型,是insert还是select,在走对应的逻辑。因为当前我这个是select,我直接截了select中的代码。第一步就是封装参数,之前参数那节课讲过的。然后进行查询。

        进入查询方法,调用的selectList方法。

         在Configuration中通过statement(全类名)获取MappedStatement对象。这个对象里面包括了该sql-select标签的全部信息。最后会在executor中进行sql调用。this.wrapCollection(parameter)这个方法也是参数封装。

         进入query方法,首先获取BoundSql对象。其实就是有sql的相关详细信息包括sql,参数等。因为咱们全局配置中开启了二级缓存。所以会有这个CacheKey。各种参数组装的key。再进入query方法。

        可以看出,即使我们使用了CacheExecutor,其实最后用的还是SimpleExecutor。CacheExecutor只不过是一个包装。从这个会查询二级缓存,没有二级缓存直接调用SimpleExecutor的query方法进行查询。

         从query方法中可以看出,mybatis先查询的是二级缓存,没有数据就会查询一级缓存。再没有就会查询数据库。进入queryFromDatabase,查看mybatis是如何查询的。

         从数据库查询完后,会再将数据放入本地缓存中,也就是一级缓存。所以说一级缓存是一直有的。这在之前的缓存机制的学习笔记中所说的是完全符合的。我们再看doQuery方法是这么实现的?方法中的参数我们都很熟悉,MappedStatement是存放该select标签的所有信息,parameter是查询参数,rowBounds是分页用的,resultHandler是返回值使用的,boundSql是含有sql相关信息

        第一步声明了一个Statement,这个Statement就是原生jdbc的。会发现有四大对象之一StatementHandler,可以创建Statement对象。进入newStatementHandler方法,进入RoutingStatementHandler方法。最终其实返回的是prepareStatement。然后通prepareStatement方法,里面就是sql和参数预编译封装到Statement中。通过handler.query()获取查询结果。

        在这里我们又发现了this.interceptorChain.pluginAll(statementHandler); 这个在Executor创建的时候也有这个。使用拦截器进行包装返回。

        首先会获取StatementType这个是select标签中的的一个属性值。默认prepare。它又会创建一个PreparedStatementHandler。

        handler.parameterize(stmt);就是参数预编译。进入该方法,parameterHandler又是一个四大对象之一。通过它来设置参数。其实在创建StatementHandler对象时,就已经创建了parameterHandler,resultSetHandler。再进入这两个对象的创建方法, 也是通过拦截器this.interceptorChain.pluginAll(resultSetHandler)创建。

        回到话题中,上面说到参数预编译:进入setParameter方法中,会看见TypeHandler 类型处理器。调用他的setParameters方法,将传过来的PrepareStatement中sql预编译设置参数。

         最后通过handler.query获取查询结果,进入query方法中,最后将处理结果使用resultHandler进行封装。

         最后也是resultHandler中也是使用TypeHandler对结果数据封装。

         增删改查执行流程图

总结

 /**
     * 首先通过inputStream读取mybatis全局配置文件,通过sqlSessionFactoryBuilder的build方法
     * 创建sqlSessionFactory对象
     *
     * 1、获取sqlSessionFactory对象:
     *  build中的方法就是,xmlConfigBuilder解析inputStream中的参数,解析文件的每一个信息保存在Configuration中,返回包含Configuration的DefaultSqlSession;
     * 注意:【MappedStatement】:代表一个增删改查的详细信息
     * <p>
     * 2、获取sqlSession对象
     * 返回一个DefaultSQlSession对象,包含Executor和Configuration;
     * 这一步会创建Executor对象;
     * <p>
     * 3、获取接口的代理对象(MapperProxy)
     * getMapper,使用MapperProxyFactory创建一个MapperProxy的代理对象
     * 代理对象里面包含了,DefaultSqlSession(Executor)
     * 4、执行增删改查方法
     * <p>
     * 总结:
     * 1、根据配置文件(全局,sql映射)初始化出Configuration对象
     * 2、创建一个DefaultSqlSession对象,
     * 他里面包含Configuration以及
     * Executor(根据全局配置文件中的defaultExecutorType创建出对应的Executor)
     * 3、DefaultSqlSession.getMapper():拿到Mapper接口对应的MapperProxy;
     * 4、MapperProxy里面有(DefaultSqlSession);
     * 5、执行增删改查方法:
     * 1)、调用DefaultSqlSession的增删改查(Executor);
     * 2)、会创建一个StatementHandler对象。
     * (同时也会创建出ParameterHandler和ResultSetHandler)
     * 3)、调用StatementHandler预编译参数以及设置参数值;
     * 使用ParameterHandler来给sql设置参数
     * 4)、调用StatementHandler的增删改查方法;
     * 5)、ResultSetHandler封装结果
     * 注意:
     * 四大对象每个创建的时候都有一个interceptorChain.pluginAll(parameterHandler);
     *
     */

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值