• mybatis执行流程


    mybatis执行流程

    ​ 记录一下自己对mybatis的理解和心得.代码是自己手写的一个mybatisDemo,比较简陋,只有一个简单的查询语句,但是麻雀虽小五脏俱全,可以理解整个mybatis的执行流程.

    重要说明:本文讲述的只是本人手写的简易mybatisDemo,可以对理解mybatis的执行流程有很大帮助.

    1. **加载全局配置文件 **

    1578378411948

    1578378435155

    1578379732510

    将配置文件加载到InputStream中,DcoumentUtils将stream转换为Document对象,根据xml文件中的标签去解析.

    1578380084046
    2. **解析数据源 **

    ​ 数据源信息解析后封装到DataSource对象中.DataSource主要作用就是封装数据源信息.再将DataSource封装到configuration中.

    1578380058334

    3. 解析mappers标签

    ​ 解析mappers标签可以得到映射文件的路径,根据路径可以找到对应的mapper.xml.

    4.解析映射文件

    ​ 同样的将映射文件读取转换为Document对象,根据标签进行解析,将解析后的信息封装到MappedStatement对象.

    1578380623971

    4.1 MappedStatement对象中主要封装如下:
    • sqlSorce:封装未解析的sql信息

    • statementType:statement的类型

    • statementId:namespace+id,这里也可以解释日常开发中映射文件id必须唯一的原因.

    • pramererTypeClass:请求参数的类型

    • resultTypeClass:结果集封装的类型

    • 最后MappedStatement对象也会封装到configuration中.

    5.解析sql信息并进行数据封装

    此时也就是sqlSource对象,sqlSource其实是一个接口.实现类主要有

    1578381919268

    • DynamicSqlSource:封装带有${}或者带有动态sql标签的sql信息

    • RawSqlSource:封装最多只带有#{}的sql信息,封装了StaticSqlSource

    • StaticSqlSource:封装最多只带有#{}的SQL信息

    • 其中sql信息是由SqlNode对象封装的.sqlNode同样也是接口,封装sql的节点信息.提供对封装的sql节点的解析.主要实现类有:

    1578382683557

    **mybatis不单单只有这四个,这个只是我的demo中写了四个. **

    IfSqlNode:封装test信息,子标签信息.

    TextSqlNode:封装的是带有${}的文本字符串

    StaticeTextSqlNode:封装的是带有#{}的文本字符串

    MixSqlNode:装的是带有${}的文本字符串

    6. 解析sql语句也是在此时进行的
    • 解析映射文件节点的时候,会判断每一个节点的类型,封装到对应sqlNode中.

    • sqlNode有一个apply()接口方法,正是此方法提供了解析功能,最终出来的sql语句封装到DynamicContext的StringBuffer中,此时出来的sql语句只是完成了字符串的拼接,还没有被解析.

    • DynamicContext:动态上下文,入参信息,解析过程中的sql信息

    • 通过ognl解析ognl表达式,#{username}中username就是ognl表达式.

    • 开始解析${}和#{},至于具体如何解析,目前本人不是很理解,会继续深入研究.

    • 此时已经得到了可以执行的sql语句,将可以执行的语句追加到DynamicContext中的StringBuffer中.

    • 将各类型的sqlNode添加到集合中封装到MixSqlNode中.

    • DynamicSqlSource:封装带有${}或者带有动态sql标签的sql信息

    • 将MixSqlNode封装到DynamicSqlSource中.

    • 前面提到过了MappedStatement中封装了SqlSource,而MappedStatement同样封装到了configuration中.此时已经解析完了全局配置文件和映射文件.

    7. 获取数据库连接
    • 本人使用了DBCP数据库连接池优化

    • 通过configuration对象获取dataSource,通过getConnection获取到数据库连接.

    8. 获取可执行的sql语句

    1578384736497

    先判断MappedStatement,如果MappedStatement对象为null的话,那么后续也没意义了,所以进行一个校验.

    1578384819465

    通过MappedStatement获取到sqlSource,前文提到过了sqlSource是一个接口,有一个接口方法是getBoundSql,三个实现类都实现了这个方法.

    • 此时涉及到了BoundSql,先说一下BoundSql

    1578384994540

    parameterMapping对象是封装解析出来的信息,就是mame和type两个值.

    所以boundSql中封装的信息就很好理解了,就是封装了解析后信息的参数集合和sql语句.

    1578385462850

    判断statementType,我这里写的只有prepared一种,后面可以继续写其他两种.

    将sql语句通过prepareStatement()方法完成拼写sql.

    1578385595698

    设置参数,简单类型就不做说明了.主要说一下POJO类型的

    parameterMapping中获取到#{username}中的username,MappedStatement中之前说过封装了parameterTypeClass请求参数类型.

    根据获取到的username通过反射拿到类中对应的字段,这里也可以解释我们日常开发中为什么属性名要和#{}里面的内容对应起来.

    此时就可以获得了可以执行的sql语句.

    9. 执行sql

    执行sql其实很简单

    rs = preparedStatement.executeQuery();
    

    只有这一行代码.rs是ResultSet,结果集.

    10. 处理结果集

    1578386182233

    前文中也说明了parameterMapping中封装了resultTypeClass,结果集的类型.通过反射new出来结果集对象.

    1578386336667

    getMetaData其实就是获取结果集的表结构信息.通过表结构信息获取到列数.

    • 根据结果集的列数遍历结果集,同样根据对应属性名将结果集完成封装.

    1578386514134

    1578386527971

    致此,本人写的mybatisDemo已经完成.感谢各位看官.

  • 相关阅读:
    [51nod 1129] 字符串最大值(kmp)
    P3391 【模板】文艺平衡树(Splay)
    次大公约数
    青蛙的约会
    [HNOI2002]营业额统计
    GYM 100741A Queries
    P3370 【模板】字符串哈希
    P3369 【模板】普通平衡树(Treap/SBT)
    05:LGTB 与偶数
    简单计算器
  • 原文地址:https://www.cnblogs.com/sx-wuyj/p/12517367.html
Copyright © 2020-2023  润新知