mybatis技术内幕笔记(一)

Scroll Down

Mybatis整体架构

Mybatis的整体架构分为三层,分别是数据支持层、核心处理层和接口层。

基础支持层

基础支持层包含整个Mybatis的基础模块,这些模块为核心处理层的功能提供了良好的支撑。

  • 反射模块
    Java中的反射虽然功能强大,但对大多数开发人员来说,写出高质量的反射代码还是有一定难度的。Mybatis中专门提供了反射模块,该模块对Java原生的反射进行了良好的封装,提供了更加简洁易用的API,方便上层调用,并且对反射操作进行了一系列优化,例如缓存了类的元数据,提高了反射操作的性能。
  • 类型转换模块
    Mybatis为简化配置文件提供了别名机制,该机制是类型转换模块的主要功能之一。类型转换模块的另一个功能是实现JDBC类型与Java类型之间的转换,该功能在为SQL语句绑定实参以及映射查询结果集时都会涉及。在为SQL语句绑定实参时,会将数据由Java类型转换为JDBC类型;而在映射结果集时,会将数据由JDBC类型转换成Java类型。
  • 日志模块
    无论在开发测试环境中,还是在线上生产环境中,日志在整个系统中地位还是非常重要的。良好的日志功能可以帮助开发人员和测试人员快速定位bug代码,也可以帮助运维人员快速定位性能瓶颈等问题。目前的Java世界中存在很多优秀的日志框架,例如Log4j、Log4j2、slf4j等。Mybatis作为一个设计优良的框架,除了提供详细的日志输出信息,还要能够集成多种日志框架,其日志模块的一个主要功能就是集成第三方框架。
  • 资源加载模块
    资源加载模块主要是对类加载器进行封装,确定类加载器的使用顺序,并提供了加载类文件以及其他资源文件的功能。
  • 解析器模块
    解析器模块的主要提供了两个功能:一个功能是对XPath进行封装,为Mybatis初始化时解析mybatis-config.xml配置文件以及映射配置文件提供支持;另一个功能是为处理动态SQL语句中的占位符提供支持。
  • 数据源模块
    数据源是实际开发中常用的组件之一。现在开源的数据源提供了比较丰富的功能。例如,连接池功能、检测连接状态等,选择性能优秀的数据源组件对于提升ORM框架乃至整个应用的性能都是非常重要的。Mybatis自身提供了相应的数据源实现,当然Mybatis也提供了与第三方数据源集成的接口,这些功能都位于数据源模块之中。
  • 事务管理
    Mybatis对数据库中的事务进行了抽象,其自身提供了相应的事务接口和简单实现。在很多场景中,Mybatis会与Spring框架集成,并由Spring框架管理事务。
  • 缓存模块
    在优化系统性能时,优化数据库性能是非常重要的一个环节,而添加缓存则是优化数据库时最有效的手段之一。正确、合理地使用缓存可以将一部分数据库请求拦截在缓存这一层,这就能够减少一部分数据库的压力。
    Mybatis中提供了一级缓存和二级缓存,而这两级缓存都是依赖于基础支持层中的缓存模块实现的。这里需要注意的是,Mybatis中自带的这两级缓存与Mybatis以及整个应用是运行在同一个JVM中的,共享同一块堆内存。如果这两级缓存中的数据量较大,则可能影响系统中其他功能的运行,所以当需要缓存大量数据时,优先考虑使用Redis、Memcache等缓存产品。
  • Binding模块
    在SqlSession相应的方法执行数据库操作时,需要指定映射文件中定义的SQL节点,如果出现拼写错误,我们只能在运行时才能发现相应的异常,为了尽早发现这种错误,Mybatis通过Binding模块将用户自定义的Mapper接口与映射配置文件关联起来,系统可以通过自定义Mapper接口中的方法执行相应的SQL语句完成数据库操作,从而避免上述问题。

核心处理层

在核心处理层中实现了Mybatis的核心处理流程,其中包括Mybatis的初始化以及完成一次数据库操作的涉及的全部流程。

  • 配置解析
    在Mybatis初始化过程中,会加载mybatis-config.xml配置文件、映射配置文件以及Mapper接口中的注解信息,解析后的配置信息会形成相应的对象并保存到Configuration对象中。待Mybatis初始化之后,开发人员可以通过初始化得到的SqlSessionFactory创建SqlSession对象并完成数据库操作。
  • SQL解析与scripting模块
    Mybatis实现动态SQL语句的功能,提供了多种动态SQL语句对应的节点。通过节点的组合使用,开发人员可以写出几乎满足所有需求的动态SQL语句。
    Mybatis中的scripting模块会根据用户传入的实参,解析映射文件中定义的动态SQL节点,并形成数据库可执行的SQL语句,之后会处理SQl语句中的占位符,绑定用户传入的实参。
  • SQL执行
    SQL语句的执行涉及多个组件,其中比较重要的是Executor、StatementHandler、ParameterHandler和ResultSetHandler。Executor主要负责维护一级缓存和二级缓存并提供事务管理的相关操作,它会将数据库相关操作委托给StatementHandler完成。StatementHandler首先通过ParameterHandler完成SQL语句的实参绑定,然后通过java.sql.Statement对象执行SQL语句并得到结果集,最后通过ResultSetHandler完成结果集的映射,得到结果对象并返回。
    mybatissqlexecutor.png
  • 插件
    Mybatis自身的功能虽然强大,但是并不能完美切合所有的应用场景,因此Mybatis提供了插件接口,我们可以通过添加用户自定义插件的方式对Mybatis进行扩展。用户自定义插件也可以改变Mybatis的默认行为。

接口层

接口层相对简单,其核心是SqlSession接口,该接口定义了Mybatis暴露给应用程序调用的API,也就是上层应用与Mybatis的桥梁。接口层在接收到调用请求时,会调用核心处理层的相应模块来完成具体的数据库操作。