Mybatis查询源代码分析
mybatis 作为常用的 orm 框架,极大的简化了我们手写jdbc代码的情况,其中它的设计还是蛮有意思的
jdbc 执行查询
在不使用 mybatis 的情况下,使用刚入门的 jdbc 执行一次查询的过程如下
public class App {public static void main(String[] args) throws Exception {Connection connection = DriverManager.getConnection("xx", null);PreparedStatement preparedStatement = connection.prepareStatement("select * from `user` where id = ?");preparedStatement.setInt(1, 1);preparedStatement.execute();ResultSet resultSet = getFirstResult(preparedStatement);if (resultSet != null) {while (resultSet.next()) {//获取 pojo 对象User user = new User();...//填充数据}}}private static ResultSet getFirstResult(Statement statement) throws SQLException {ResultSet resultSet = statement.getResultSet();while (resultSet == null) {if (statement.getMoreResults()) {resultSet = statement.getResultSet();} else {if (statement.getUpdateCount() == -1) {// no more results. Must be no resultsetbreak;}}}return resultSet;}
这个过程基本上可以概括为如下
- 获取物理链接(Connection) ——> 第三行
- 预编译 ——> 第四行,设置resultSet参数
- 设置参数 + 执行sql ——> 第五行+第六行
- 处理结果集 ——> 第7行到结束
整个 mybatis 的处理流程也是一致的,从根本上简化了我们写jdbc的代码,同时也带来了一定的损耗(相对于jdbc而言),但是这点损耗和维护性来说,是值得接受的
mybatis 执行查询
mybatis 执行一次查询的过程如下
- 读取配置文件,获取
SqlSessionFactoryBuilder - 解析配置文件,获取
SqlSessionFactory- 解析
configuration.xml- 解析配置的属性元素,例如
cacheEnabledlocalCacheScope, 解析别名等等。 - 解析
mapper.xml文件- 解析
ResultMap,paratemerMapsqlcurd节点,为每一个curd节点配置一个MappedStatement对象
- 解析
- 解析配置的属性元素,例如
- 解析
- 获取
SqlSession—>sqlSessionFactory.openSession(xxxx) - 事务
TransactionFactory - 执行器
Executor new DefaultSqlSession(configuration, executor, autoCommit)- 执行
mybatis方法 ——>performDataDao.selectPerformDataByKey(1234571443)- 获取对应
statementId的MappedStatement对象委托给executor#query继续执行 - 跳过缓存,查询db,获取
PreparedStatementHandler,执行预编译,设置参数- 预编译
connection.prepareStatement(sql)—-> PreparedStatementHandler#instantiateStatement - 设置参数
preparedStatement.setInt(1, 1);—-> DefaultParameterHandler#setParameters,将包转过的参数根据parameterType/Map设置
- 预编译
- 执行查询,处理结果集合
- 反射获取 pojo 对象,填充参数
- 获取对应
整个流程不算清晰,但是也能大致的说明 mybatis 的执行过程,具体可分为 解析配置文件 请求处理器 请求处理后
- 解析配置文件
configuration.xml 和 mapper,xml,configuration对象的参数填充MappedStatement对象的填充,Resultmap 解析,Sql 节点解析 等等
- 请求处理前
- 预编译,设置参数,设置超时时间,设置fetchSize,设置ResultSetType
- 请求处理后
- 处理结果集,
RowBound处理,ResultMap处理(反射pojo,参数填充)
- 处理结果集,
解析配置文件
请求处理前
请求处理后
小结
2018-10-22
