现在做java开发几乎每天都要使用mybatis,但是很多人只是会用,并不知道原理,看了《mybatis源码深度解析》这本书之后,对mybatis了全面的一个了解,这里结合案例对自己的理解做个总结,希望对读者有帮助。
如下是一段使用mybatis是简单实例:
整个执行流程如下:
一、通过Resources加载配置好的mybatis.xml配置文件
Resources是ibatis.io包下面的类,也就是一个io流,用于读写文件,通过getResourceAsStream把xml文件加载进来,把配置文件解析为一个流。
二、获取SqlSessionFactory
我们首先new了一个SqlSessionFactoryBuilder对象,他是SqlSessionFactory的构建者。我们调用了他的build()方法:
可以看到这里调用了XMLConfigBuilder的parse()方法
接下来调用了 parseConfiguration(XNode root)方法,在这个方法里面解析了配置文件中的各节点
配置文件解析完成返回了Configuration对象,得到这个对象之后我们调用了下面这个方法
方法里面没有其他处理,只是返回了DefaultSessionFactory对象,这个对象是SqlSessionFactory对象的实现类,这样就获取到了SqlSessionFactory。这里使用了建造者模式,不管xml配置了什么内容,我们都会返回SqlSessionFactory对象。
三、获取SqlSession
我们继续往下走,上一步我们获取到SqlSessionFactory对象了,接下来调用了openSessionI()方法。
可以看到这里直接调用了openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit)方法
到此为止我们就获取到了sqlSession对象了。
四、jdk动态代理生成mapper接口的代理对象
可以看到我们直接调用了getMapper()方法来获取mapper对象。
跟到DefaultSqlSession类中可以看到
我们可以看到这里是调用了Configuration类中的getMapper方法,如下
这里实际调用了MapperRegistry类的getMapper方法,如下
可以看出来这里返回了mapper接口的代理实例类
这里是通过JDK动态代理实现的
五、 通过第四步返回的代理对象执行方法
MyBatis中的MapperProxy实现了InvocationHandler接口,用于实现动态代理相关逻辑。熟悉JDK动态代理机制的读者都知道,当我们调用动态代理对象方法的时候,会执行MapperProxy类的invoke()方法。该方法的内容如下:
接下来进入MapperMethod类中:
这里判断sql的执行类型 ,根据id查询我们调用的是DefaultSqlSession类中的selectOne方法
这里可以看出来实际调用的还是selectList方法。
至此,mybatis整个调用过程就过了一遍了,还有一些点没讲到的后续再补充,希望这篇博客对你理解mybatis有帮助。