MyBatis源码分析

传统方式

  1. 将mybatis-config.xml加载入inputStream中。
  2. 调用sqlsessionFactotyBuilder().build()方法,将流传入其中。
  3. sqlsessionFactotyBuilder().build()方法中有一个XMLConfigBuilder类解析xml中的内容,封装为一个configuration实例,configuration对象的结构和xml配置文件的对象几乎相同。
  4. 且mybatis-config.xml中的mappers标签映射的mapper.xml或者配置mapper接口的目录,每一个查询sql标签都会被解析封装成一个MappedStatement对象,然后存储在 Configuration对象的mappedStatements属性中,mappedStatements是一个HashMap,存储时key = 全限定类名 + 方法名, value = 对应的 MappedStatement对象。
  5. 到此对xml配置文件的解析就结束了,回到build()方法返回一个sqlSessionFactory对象,并将configuration对象传入其中。
  6. 再进入sqlSessionFactory.openSession()方法,在内部为configuration创建指定类型的Executor,返回一个DefaultSqlsession(configuration, executor,//事务隔离级别autoCommit);
  7. 执行sqlSession中的api,方法内部实现是根据传入的全限定类名+方法名从映射的map中取出MapperStatement对象,调用Executor执行器进行处理,例如executor.query(),根据MapperStatement对象中的parameterType参数动态获取到SQL语句,最后返回BoundSql对象表示,再为本次查询创建缓存的key。
  8. 根据key值从缓存中查询,若缓存中没有就从数据库中查询,查询出来后把结果放入缓存,若缓存中有则直接从缓存中获取。
  9. 从数据库查询的过程:根据传入参数创建JDBC的Statement连接对象,再将所有必要参数传给StatementHandler来完成对数据库的查询,最终返回结果集。
  10. 这里的StatementHandler主要完成两个工作,一是对JDBC的Statement对象里的占位符进行设值,二是执行数据库操作,并将Statement对象返回的结果集封装为具体的对象。

Mapper代理方式

通常Mapper接口我们什么方法都没有实现确可以使用,利用了动态代理的机制,

首先介绍一下MyBatis初始化时对接口的处理:MapperRegistry是Configuration中的一个属性,内部维护一个HashMap用于存放mapper接口的工厂类,每个接口对应一个工厂类。

  1. 前面的步骤都一样,有区别的地方在于,封装configuration实例时,mybatis-config.xml的mappers标签内配置的是接口的包路径,当解析到是接口时会创建此接口对应的MapperProxyFactory对象,存入HashMap中,Key = 接口的字节码对象,value = 此接口对应的MapperProxyFactory对象。
  2. sqlSession.getMapper(UserMapper.class)方法,根据传入的字节码对象从MapperRegistry中的HashMap中拿到MapperProxyFactory对象,如果该对象是为null的,就抛出异常,如果不为null就通过动态代理生成实例。
  3. 代理对象调用方法时,都要执行动态代理实例中的invoke()方法,内部是获取了一个mapperMethod对象,调用它的execute()方法。
  4. execute()方法根据mapper中的类型以及接口的返回值类型来判断具体调用SqlSession中的哪个方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值