MyBatis源码解析之架构设计

144 阅读5分钟

背景

Mybatis本是apace的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到google code,改名为MyBatis。是一个基于Java的持久层框架。

无论是Mybatis、Hibernate都是ORM的一种实现框架,均是对JDBC的一种封装。

  • Hibernate是一个老旧的框架,用起来比较舒服,什么SQL代码都不用写,但是在处理复杂业务和复杂SQL缺乏灵活性,比较难实现也不好理解
  • JDBC比较容易理解,按照步骤配置就好了,就是开发起来比较麻烦(什么都要开发干),然后SpringDAO其实就是JDBC的一层封装。
  • Mybatis是jdbc和Hibernate之间的一个平衡点,纯粹地说是个半ORM框架

架构概览

Mybatis框架整体设计如下:

接下来一一讲解每个层所负责的事项:

接口层

该层主要定义Mybatis和数据库交互的方式:

  • 使用传统的Mybatis提供的API

这是传统的传递Statement Id 和查询参数给SqlSession对象,使用SqlSession对象完成和数据库的交互;Mybatis提供了便利丰富的API,维护调用层与数据库连接信息和Mybatis自身配置信息以及对数据库的增删改查数据操作

上述使用的方法,就是创建一个和数据库打交道的SqlSession对象,然后根据Statement Id和参数来操作数据库,但是这种方式不太符合面向对象和面向接口编程的习惯。

  • 使用Mapper接口

Mybatis为了适应面向接口编程的趋势,增加了使用Mybatis支持Interface调用的方式

Mybatis将配置文件中的每个节点抽象为一个Mapper接口,而这个接口中声明的方法跟节点中的<select|update|delete|insert>节点项对应,即<select|update|delete|insert>节点的id值为Mapper接口中的方法名称,parameterType值便是对应方法的入参类型,resultMap则对应接口表示的返回类型或者返回结果集的元素类型

根据Mybatis的配置规范配置好之后,SqlSession.getMapper(xxMapper.class)方法,Mybatis会根据相应的接口声明方法信息,通过动态代码机制生成一个Mapper实例,我们使用Mapper接口的其中一个方法时,Mybatis会根据这个方法的方法名和参数类型,确定Statement Id,底层还是通过SqlSession.select|update("statementId", paramenterObject)来实现对数据库的操作的,这种Mapper接口方式,就是为了满足面向接口编程的需求

数据处理层

该层是Mybatis的核心,主要完成两个功能:

  • 通过传入参数构建动态SQL语句;
  • SQL语句的执行以及封装查询结果继承List

参数映射和动态SQL语句生成

动态语句生成是Mybatis框架中非常值得学习的一点,通过传入的参数值,使用Ognl动态构造SQL语句,使得Mybatis有很强的灵活性和扩展性。

参数映射指的是对于java数据类型和jdbc数据类型之间的转换,包含两个过程:

  • 查询阶段:将java类型数据转换成jdbc类型的数据,通过preparedStatement.setXXX() 来设值
  • 结果转换:对resultset查询结果集的jdbcType数据转换成java数据类型

SQL语句的执行以及封装查询结果集成List

动态SQL语句生成之后,Mybatis将执行SQL语句,并将返回的结果集转换成List列表。Mybatis在对结果集的处理中,支持结果集关系一对多和多对一的转换

框架支撑层

  • 事务管理机制

事务管理机制对于ORM框架而言是不可缺少的一部分,事务管理机制的质量也是考量一个ORM框架是否优秀的一个标准。

  • 连接池管理机制

由于创建一个数据库连接所占用的资源比较大,对于数据吞吐量大和访问量非常大的应用而言,连接池的设计显得非常重要

  • 缓存机制

为了提高数据利用率和减少服务器和数据库的压力,Mybatis会对一下查询提供会话级别的数据缓存,会将一次查询,放到SqlSession中,在允许的时间内,对完全相同的查询,Mybatis会直接将结果返回,不用查询数据库

  • SQL语句的配置方式

传统的Mybatis配置SQL语句的方式利用XML文件进行配置的,为了更好的支撑面向接口编程,Mybatis引入了Mapper接口的概念,有了接口的引入,对使用注解来配置SQL比较便利,但是当前对注解配置SQL语句只有有限的支持,复杂的SQL语句还需依赖XML配置。

引导层

引导层是配置和启动MyBatis配置信息的方式。MyBatis 提供两种方式来引导MyBatis :基于XML配置文件的方式和基于Java API 的方式。

相关组件之间调用关系

主要的核心组件功能:

  • SqlSession:作为Mybatis工作的主要顶层API,表示和数据库交互的会话,完成数据CURD操作
  • Excutor:Mybatis执行器,是Mybatis调度的核心,负责SQL语句的生成和查询
  • StatementHander:封装了JDBC Statement操作,负责对JDBC statement操作,如参数设置、将Statement结果转换成List集合。
  • ParameterHandler:负责对用户传递参数转换JDBC Statement 所需要的参数
  • ResultHander:负责将JDBC返回的Result结果集对象转换成List类型对象
  • TypeHandler:负责java数据类型和jdbc数据类型之间的映射和转换
  • MappedStatement:维护mapper里面<select|update|insert|delete>节点的封装
  • SqlSource:根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回
  • BoundSql:表示动态生成的SQL语句以及相应的参数信息
  • Configuration:MyBatis所有的配置信息都维持在Configuration对象之中。