深入分析mybatis工作原理

Mybatis分析

通过分析了mybatis的源码我觉得大致分为三步

1. 获取数据源:

SqlSessionFactory.build(inputStream)–>XMLConfigBuilder–>Parse–>PaseConfiguration–>build(Configuration)–>DefaultSqlSessionFactory–>DataSource

2. 获取sql

openSession()–>DefaultSqlSession–>getMapper()–>execute–>getBoundSq

3. . 执行sql(SqlSession)

SimpleExecutor–>query()–>createCacherKey–>doQuery–>newStatementHander–>prepareStatement—>instantiateStatement

mybatis执行流程

在这里插入图片描述

接下说一下具体流程

一、根据配置文件创建SqlSessionFactory
  1. 创建SqlSessionFactoryBuilder 对象 SqlSessionFactoryBuilder
  2. 调用build(inputStream)方法 XMLConfigBuilder
  3. 创建解析器 parser
  4. 解析每一个标签把详细信息保存在Configuration中 Configuration
  5. 解析mapper.xml 把mapper.xml 中的每一个元素信息解析出来并保存,在全局配置中将增删改查标签的每一个标签每一个属性都解析出来
  6. 返回Configuration
  7. bulid(Configuration)
  8. new DefaultSqlSession()
  9. 返回创建的DefaultSqlSession,包含了保存全局配置信息的Configuration
    10.最终返回DefaultSQLSessionFactory

总结:Configuration 封装了所有配置文件的信息, 把配置文件的信息解析并保存在Configuration对象中,返回包含了Configuration对象的DefaultSqlSession对象

二、返回SqlSession的实现类DefaultSqlSession对象,它里面包含了Configuration和Executor(Executor会在这一步被创建
  1. 调用openSession方法
  2. openSessionFromDataSource()
  3. 创建一些信息,创建事务等
  4. newExecutor()
  5. 根据Executor在全局配置中的类型,创建出SimpleExecutor/ReuseExecutor/BatchExecutor 说明:Executor接口中定义了增删改查的方法
  6. 如果有二级缓存,就会创建CachingExecutor(executor)
  7. 调用interceptorChan.plugnAll(executor) 说明:使用每一个拦截器重新包装executor并返回
  8. 创建DefaultSqlSession,包含了Configuration和Executor
  9. 最终返回DefaultSqlSession
三、getMapper返回接口的代理对象(包含了SqlSession对象)
  1. DefaultSqlSessionFactory.sqlSession() 调用Configuration.getMapper(type),,又会从MapperRegistry调用getMapper()拿到MapperproxyFactory
  2. 根据接口类型获取MapperProxyFactory
  3. 然后newInstance(SqlSession)
  4. 创建MapperProxy,他是一个invocationHandler(动态代理需要的)
  5. 创建MapperProxy()代理对象
  6. 返回MapperProxy代理对象
四、执行查询
  1. MapperProxy----invoke()-----MapperMethod----execute(SqlSession,args)
  2. 判断增删改查类型
  3. 包装参数为一个map或者直接返回
  4. 调用SqlSession.selectOne() 最终调用selectList()
  5. 获取MappedStatement executor.query(ms,xx,x)
  6. 通过MappedStatement.getBoundSql()获取到绑定的sql语句
  7. 查看本地缓存是否有数据,没有就调用queryFromDatabase,查出后会保存到本地缓存
  8. doquery()
  9. 创建statementHandler对象,PreparedStatementHandler
  10. 调用interceptorChan.plugnAll(statementHandler) 说明:使用每一个拦截器重新包装executor并返回
  11. 创建ParameterHandler 调用interceptorChan.plugnAll(ParameterHandler)
  12. 创建ResultSethandler 调用interceptorChan.plugnAll(resultSethandler)
  13. 预编译sql,产生PreparedStatement对象
  14. 调用ParameterHandler来设置参数
  15. 调用TypeHandler来预编译设置参数
  16. 查出数据使用resultHandler处理结果、使用typeHandler获取value值
  17. 后期关闭连接等操作
  18. 如果只有一条数据,返回查询list的第一个

查询流程总结:
代理对象–》DefaultSqlSession–》Executor–》StatementHandler—设置参数—ParameterHandler — TypeHandler -----原生的JDBC,Statement,PreparedStatement—处理结果— ResultSethandler—
statementHandler:处理sql语句预编译,设置参数的相关工作
ParameterHandler: 设置预编译参数用的
ResultSethandler:处理查询后的结果集
TypeHandler:在整个过程中,进行数据库类型和javaBean类型的映射.

五、mybatis总结:
  1. 根据配置文件(全局,sql映射) 初始化出Configuration对象,
  2. 创建出DefaultSqlSession对象,它里面包含了Executor(根据全局配置文件中defaultExecutorType创建出对应的Executor)和Configuration
  3. DefaultSqlSession.getMapper(),难道对应接口的MapperProxy,
  4. MapperProxy里面有DefaultSqlSession
  5. 执行增删改查
    1、调用DefaultSqlSession的增删改查
    2、会创建StatementHandler对象。(同时也会创建ParameterHander和ResultSetHandler)
    3、调用Statementhandler预编译参数以及参数值
    使用ParamterHandler来给sql设置参数
    4、调用StatementHandler的增删改查方法
    5、ResultSetHandler封装接口

最后补充一点

mybaits插件原理
在四大对象创建的时候
1. 每个创建出来的对象不是直接返回的,而是interceptorCHan.pluginAll(parameterhandler);
2. 获取到所有的Interceptor(拦截器)(插件需要实现的接口),调用interceptor。披露滚(target);返回target包装后的对象
3. 插件机制,我们可以使用插件目标对象创建一个代理对象,AOP,我们的插件可以为四大对象创建代理对象,代理对象可以拦截到四大对象的每一个执行

我想大家如果把这个掌握,mybatis的执行流程才能完全掌握,如果是面试的话,挑些重要的说说感觉就没什么问题,当然,如果你大部分都能说下来,效果会更好,可能有些细节,面试官都没有注意到过。

如果这篇文章对大家有一点帮助,点个赞哈。。。。。。。。。。。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值