欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MyBatis源码浅析(一)开篇

程序员文章站 2024-03-11 13:50:49
源码学习的好处不用多说,mybatis源码量少、逻辑简单,将写个系列文章来学习。 sqlsession mybatis的使用入口位于org.apache.ibatis....

源码学习的好处不用多说,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的作者故意这样设计的。虽然框架从整体来看是半自动的,但灵活性却得到了极大增加。