37

手写mybatis彻底搞懂框架原理

 4 years ago
source link: https://www.tuicool.com/articles/Vr67Nz
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

mybatis的前身是iBatis,其源于“Internet”和“abatis”的组合,是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。 mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集,它可以使用简单的XML或注解来配置和映射原生信息,将接口和Java的POJO映射成数据库中的记录。

jEzaQbf.jpg!web

mybatis的架构设计

qYbYFv6.jpg!web

Mybatis的功能架构分为三层:

  • 接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层接收到调用请求就会调用数据处理层来完成具体的数据处理。

  • 数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。

  • 框架支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

mybatis的运行流程

fyIFjeA.jpg!web

  1. 加载配置:配置来源于两个地方,配置文件和注解。将SQL的配置信息加载成为MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。

  2. SQL解析:当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。

  3. SQL执行:将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果。

  4. 结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,并将最终结果返回。

手写mybatis的目录

来看下笔者的手写mybatis的文件目录。 查看Bootstrap文件上说明,然后运行该文件,断点调试即可一步步了解mybatis框架的原理了。 (很多地方都注解了,方便初学者更多了解框架细节)

FRrAVvy.jpg!web

代码地址请查看,https://github.com/y277an/java-you-need-know 再看看正版的代码结构吧。

考虑到transaction对理解框架原理产生干扰,所以代码全部删掉

mybatis目录结构及内容

以下目录对照的是mybatis-3.5.1的源码。

  • annotations。注解目录。包括所有的注解,如@SELECT,@UPDATE等。

  • binding。Mapper类的实例反射生成工具目录。

  • builder。主要是注解,mapper和SqlSource的构造器及转换器。

  • cache。Mybatis内部缓存接口。实现了一些特定的缓存策略,FifoCache、LruCache、BlockingCache、LoggingCache等。

  • dataSource。数据源工厂类及实现。实现类包括JndiDataSourceFactory、PooledDataSourceFactory和UnpooledDataSourceFactory。数据源实现类:UnpooledDataSource和PooledDataSource。

  • exceptions。Mybatis自定义的异常类,都继承自RuntimeException。

  • executor。执行器相关包。包括Key生成器、加载器(包括Cglib、Javassist的代理,结果加载器)、参数处理器接口、结果处理器、结果集(resultSet)处理器、Statement处理器(实现类:BaseStatementHandler、CallableStatementHandler、PreparedStatementHandler、RoutingStatementHandler、SimpleStatementHandler)、执行器(SimpleExecutor、ReuseExecutor、CachingExecutor、BatchExecutor、BaseExecutor)。

  • io。主要是定义的几个VFS(VFS、DefaultVFS、ClassLoaderWrapper)。

  • jdbc。与Sql相关的操作。如Sql运行器,脚本运行器和Sql封装类等。

  • logging。各个类型的日志适配器,都实现了Log接口。StdOutImpl、Slf4jImpl、NoLoggingImpl、Log4j2Impl、Log4jImpl、Jdk14LoggingImpl、BaseJdbcLogger和JakartaCommonsLoggingImpl。

  • mapping。主要是接口参数,sql和返回结果的映射类,主要类包括:MappedStatement、ParameterMap、ParameterMapping、ResultMap、ResultMapping、BoundSql和SqlSource等类。

  • parsing。变量解析,如解析${},#{}等。

  • plugin。主要包含插件的定义接口。如Interceptor、Plugin和InterceptorChain等。

  • reflection。主要是一些反射操作的工具方法和对象工厂类,以及一些常用的包装类,如BaseWrapper、BeanWrapper、CollectionWrapper、MapWrapper和ObjectWrapper。

  • scripting。执行驱动和动态Sql解析的处理器。

  • session。主要是SqlSession和SqlSessionFactory。

  • transaction。主要是mybatis简单封装的jdbc事务操作类。

  • type。各个类型数据的处理器。用于动态的设置参数和转换数据,如IntegerTypeHandler用来处理Integer类型的值的set和get操作。除了八大基本类型,还有常用的集合及Map类型,还增加了各种时间类型的处理器。

MyBatis的核心成员和职责

从MyBatis代码实现的角度来看,MyBatis的核心组件如下

i6FbyuN.jpg!web

  • SqlSession。作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能。

  • Executor。MyBatis执行器,是MyBatis调度的核心,负责SQL语句的生成和查询缓存的维护。

  • StatementHandler。封装了JDBC Statement操作,负责对JDBCstatement的操作,如设置参数、将Statement结果集转换成List集合。

  • ParameterHandler。负责对用户传递的参数转换成JDBC Statement 所需要的参数。

  • ResultSetHandler。负责将JDBC返回的ResultSet结果集对象转换成List类型的集合。

  • TypeHandler 负责java数据类型和jdbc数据类型之间的映射和转换。

  • MappedStatement。MappedStatement维护了一条<select|update|delete|insert>节点的封装。

  • SqlSource。负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回。

  • BoundSql。表示动态生成的SQL语句以及相应的参数信息。

  • Configuration。MyBatis所有的配置信息都维持在Configuration对象之中。

更多内容,欢迎关注微信公众号:全菜工程师小辉 ~

FFz2Ef2.png!web

j2uIny6.gif

“阅读原文” 一起来充电吧!

喜欢就点个“在看”呗 ^_^


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK