从一个小例子说一下mybatis执行一条sql的流程
示例代码
String resource = "org/mybatis/example/mybatis-config.xml"; //1
InputStream inputStream = Resources.getResourceAsStream(resource); //2
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //3
SqlSession session = sqlSessionFactory.openSession();//4
session.getMapper(UserMapper.class);//5
第1、2步可以跳过了,主要做的就是把这个文件加载到一个输入流中
第三步build方法点进去
可以看到new了一个XMLConfigBuilder对象,
92行parser.parse()方法点进去
可以看到XMLConfigBuilder就是解析/configuration下面的一些标签
157行点进去
可以看到有一个XMLMapperBuilder对象
随便选一个mapperParser.parse()方法点进去
101行的configurationElement方法点进去
由此可知XMLMapperBuilder是用来解析这些标签的(不包括select|insert|update|delete开头的,这些是XMLStatementBuilder干的粗活)
等这些标签解析完会放到一个Configuration 大对象中,最后返回DefaultSqlSessionFactory。
标签解析完毕
然后回到刚开始出生的地方,看这行代码
SqlSession session = sqlSessionFactory.openSession();//4
第四步
openSession方法点进去
openSessionFromDataSource点进去,可以看到最后返回一个DefaultSqlSession
可以点进105行的newExecutor方法,mybatis四大核心对象之一Executor就是在这创建的
创建session完毕,再回到出生的地方
session.getMapper(UserMapper.class);//5
第5步,这里就是sql执行的关键流程了
getMapper方法一路点下去
啥,发现了一个代理工厂,mapperProxyFactory,这个就是最终干活的人,点进它的56行代码
通过以上的动态代理,咱们就可以方便地使用dao接口啦, 就像之前咱们写的demo那样:
这下方便多了吧, 呵呵, 貌似mybatis的源码就这么一回事儿啊。
别急,还没完, 咱们还没看具体是怎么执行sql语句的呢。
上面,咱们拿到了MapperProxy, 每个MapperProxy对应一个dao接口, 那么咱们在使用的时候,MapperProxy是怎么做的呢?
交给mapperMethod去执行,点进去
咱们看78行只查询1条记录的情况吧
selectOne方法点进去
可以看到它最终调了selectList方法只返回一条数据,selectList方法点进去
executor.query,执行器开始执行查询了
150行query方法点进去
大概意思就是先去从缓存中去查,查不到再去数据库中去查,queryFromDatabase方法点进去
339行点进去,选择SimpleExecutor这个类
可以看到有个StatementHandler被74行的prepareStatement方法当做参数传进去了,可以prepareStatement方法一路点下去,你最后会发现它调用了PreparedStatementHandler类中的
instantiateStatement方法设置参数
然后在看上上图的doQuery方法的76行handler.query点进去,选择PreparedStatementHandler这个类
可以看到和jdbc查询数据库的东西一样,PreparedStatement,最后返回的结果集用ResultSetHandler包装一下,至此,mybatis一个执行sql的流程分析完毕。
总结,mybatis用XMLConfigBuilder,XMLMapperBuilde,XMLStatementBuilder来解析配置文件,解析完成后放到一个Configuration 大对象中,Configuration 放到DefaultSqlSessionFactory
中,返回这个工厂,解析完成后会创建一个DefaultSqlSession,然后开始执行sql语句,运用代理
模式,先查询缓存,查不到再查询数据库后放到缓存中,其中查询时用到了mybatis的四大核心对象
Executor:MyBatis的执行器,用于执行增删改查操作
StatementHandler:数据库的处理对象,用于执行SQL语句
ParameterHandler:处理SQL的参数对象
ResultSetHandler:处理SQL的返回结果集
最后返回查询到的结果
以上是个人理解,溜了…