MyBatis源码浅析(一)开篇
源码学习的好处不用多说,mybatis源码量少、逻辑简单,将写个系列文章来学习。
sqlsession
mybatis的使用入口位于org.apache.ibatis.session包中的sqlsession,发现它是个接口,必然有个默认实现类org.apache.ibatis.session.defaults包中的defaultsqlsession。我们从来没有new过这个类,按照java惯例使用sqlsessionfactory里的工厂方法。发现它也是个接口,必然有默认实现类defaultsqlsessionfactory。该类依然不用自己创建,使用sqlsessionfactorybuilder里的工厂方法。
defaultsqlsession
defaultsqlsession里主要方法:
1)cursor<t> selectcursor(string statement, object parameter, rowbounds rowbounds),委托给executor.querycursor(ms, wrapcollection(parameter), rowbounds)。
2)list<e> selectlist(string statement, object parameter, rowbounds rowbounds)和void select(string statement, object parameter, rowbounds rowbounds, resulthandler handler),委托给executor.query(ms, wrapcollection(parameter), rowbounds, handler)。
3)int update(string statement, object parameter),委托给executor.update(ms, wrapcollection(parameter))。
可见,最终都有executor来完成。
executor
executor位于org.apache.ibatis.executor包中,是个接口,实现类是baseexecutor和cachingexecutor。其中baseexecutor是抽象的,有三个子类simpleexecutor、reuseexecutor和batchexecutor,见名知意。baseexecutor里主要方法:
1)list<e> query(mappedstatement ms, object parameter, rowbounds rowbounds, resulthandler resulthandler, cachekey key, boundsql boundsql)和list<e> queryfromdatabase(mappedstatement ms, object parameter, rowbounds rowbounds, resulthandler resulthandler, cachekey key, boundsql boundsql),委托为抽象的abstract <e> list<e> doquery(mappedstatement ms, object parameter, rowbounds rowbounds, resulthandler resulthandler, boundsql boundsql)。
2)cursor<e> querycursor(mappedstatement ms, object parameter, rowbounds rowbounds),委托给抽象的abstract <e> cursor<e> doquerycursor(mappedstatement ms, object parameter, rowbounds rowbounds, boundsql boundsql)。
3)int update(mappedstatement ms, object parameter),委托给抽象的abstract int doupdate(mappedstatement ms, object parameter)。
基类处理公共部分,具体留给子类实现。
再看下simpleexecutor里的主要方法:
1)list<e> doquery(mappedstatement ms, object parameter, rowbounds rowbounds, resulthandler resulthandler, boundsql boundsql),委托给handler.<e>query(stmt, resulthandler)。
2)cursor<e> doquerycursor(mappedstatement ms, object parameter, rowbounds rowbounds, boundsql boundsql),委托给handler.<e>querycursor(stmt)。
3)int doupdate(mappedstatement ms, object parameter),委托给handler.update(stmt)。
可见,最终由handler来处理。
statementhandler
statementhandler位于org.apache.ibatis.executor.statement包中,是个接口,实现类是basestatementhandler和routingstatementhandler。basestatementhandler是抽象的,有三个子类simplestatementhandler、preparedstatementhandler和callablestatementhandler。这三个应该比较熟悉,分别处理不带参数的sql语句、参数化sql语句和存储过程。再看simplestatementhandler里的主要方法:
1)list<e> query(statement statement, resulthandler resulthandler),委托给statement.execute(sql)。
2)cursor<e> querycursor(statement statement),委托给statement.execute(sql)。
3)int update(statement statement),委托给statement.execute(sql)。
最终由statement执行sql。这就回到了java.sql包了。
mybatis主要完成对sql参数的封装处理、结果集的获取并生成对象,而把sql语句的构建过程留给用户。mybatis的作者故意这样设计的。虽然框架从整体来看是半自动的,但灵活性却得到了极大增加。
推荐阅读
-
MyBatis源码浅析(一)开篇
-
ArrayList其实就那么一回事儿之源码浅析
-
HashSet其实就那么一回事儿之源码浅析
-
HashMap其实就那么一回事儿之源码浅析
-
mybatis 一级缓存 源码解析
-
Mybaits 源码解析 (十二)----- Mybatis的事务如何被Spring管理?Mybatis和Spring事务中用的Connection是同一个吗?
-
Mybaits 源码解析 (十)----- 全网最详细,没有之一:Spring-Mybatis框架使用与源码解析
-
Mybatis源码解析,一步一步从浅入深(七):执行查询
-
Mybaits 源码解析 (一)----- 搭建一个mybatis框架(MyBatis HelloWorld)
-
结合Mybatis源码说说sqlSession创建流程和从中用到的一些设计模式