MyBatis源码探究(一)

MyBatis源码探究 一

  • 一、概述
    • Hibernate
    • mybatis
    • spring jdbc
  • 二、MyBatis 整体架构
    • 模块相应介绍
      • 基础支持层
      • 核心处理层
      • 接口层

一、概述

Hibernate

Hibernate 是一款 Java 世界中最著名的 ORM 框架之一,作为一个老牌的 ORM 框架, 经受住了 Java EE 企业级应用的考验,替代 了复杂的 Java EE 中 EJB 解决方案, 一度成为 Java ORM 领域的首选框架。

Hibernate 通过 hbm.xml 映射文件维护 Java 类与数据库表的映射关系。 通过 Hibernate 的映 射, Java 开发人员可以用看待 Java对象的角度去看待数据库表中的数据行。数据库中所有的表 通过 hbm皿nl 配置文件映射之后,都对应一个 Java 类, 表中的每一行数据在运行过程中会被映 射成相应的 Java对象。在 Java对象之间存在一对多、一对一、多对多等复杂的层次关系,Hibernate 的 hbm.xml 映射文件也可以维护这种层次关系, 并将这种关系与数据库中的外键、 关联表等进 行映射,这也就是所谓的“关联映射”。

  • 能够实现对象模型与关系模型的映射
  • 帮助开发人员屏蔽不同数据库 产品中 SQL 语句的细微差异
  • .......等(略)

能够实现对象模型与关系模型的映射

mybatis

MyBatis并不是一个完整的ORM框架,ORM是Object和Relation之间的映射,包括Object->Relation和Relation->Object两方面。Hibernate是个完整的ORM框架,而MyBatis完成的是Relation->Object,也就是其所说的data mapper framework。关于ORM的一些设计思路和细节可以参见Martin Flow《企业应用架构模式》一书中的ORM章节,MyBatis并不刻意于完成ORM(对象映射)的完整概念,而是旨在更简单、更方便地完成数据库操作功能,减轻开发人员的工作量,我想这对于应用系统来说也是最实用的,相信用Hibernate的都受过它的痛苦,而用过MyBatis的都会感觉它很简捷轻松。

spring jdbc

严格来说, Spring JDBC 并不能算是一个 ORM 框架,它仅仅是使用模板方式对原生 JDBC 进行了一层非常薄的封装。使用 Spring JDBC 可以帮助开发人员屏蔽创建数据库连接对、 Statement 对象、异常处理以及事务管理的重复性代码,提高开发效率。

Spring JDBC 中没有映射文件、对象查询语言、缓存等概念,而是直接执行原生 SQL 语句。 Spring JDBC 中提供了多种 Template 类,可以将对象中的属性映射成 SQL 语句中绑定的参数,Spring JDBC 还提供了很多 ORM 化的 Callback,这些 Callback 可以将 ResultSet 转化成相应的对 象列表。在有些场景中,我们需要直接使用 JDBC 原生对象,例如,操作 JDBC 原生的 ResultSet, 则可以直接返回 SqlRowSet 对象,该对象是原生 ResultSet 对象的简单封装。 Spring JDBC 在功 能上不及 Hibernate 强大,但它凭借高度的灵活性,也在 Java 持久化中占有了一席之地。

除此之外, Spring JDBC 本身就位于 Spring 核心包中,也是 Spring 框架的基础模块之一, 天生与 Spring 框架无缝集成。凭借 Spring 框架的强大功能, Spring JDBC 可以实现集成多种开 源数据源、管理声明式事务等功能。总的来说, Spring JDBC 可以算作一个封装良好、功能强 大的 JDBC 工具集。 Spring JDBC 整体架构设计非常优秀,其源码也非常值得分析,感兴趣的读 者可以深入学习一下。

二、MyBatis 整体架构

My Batis 的整体架构分为三层, 分别是基础支持层、 核心处理层和接口层。
MyBatis源码探究(一)_第1张图片

模块相应介绍

基础支持层

  • 反射模块
    MyBatis 中专门提供了反射模块,该模块对 Java 原生的反射进行了良 好的封装,提供了更加简洁易用的 API,方便上层使调用,并且对反射操作进行了一 系列优化,例如缓存了类的元数据,提高了反射操作的性能。

  • 类型转换模块

    • MyBatis 为简化配置文件提供了别名机制, 该机制是类型转换模 块的主要功能之一
    • 实现JDBC类型与Java 类型之间的转换
  • 日志模块
    日志模块的一个主要功能就是集成第三 方日志框架。
    Log4j、 Log4j2, slf4j 等。

  • 资源加载模块
    主要是对类加载器进行封装,确定类加载器的使用顺序,并提供了加载 类文件以及其他资源文件的功能。

  • 解析器模块

    • 对 XPath 进行封装,为 MyBatis 初始 化时解析 mybatis-config.xml 配置文件以及映射配置文件提供支持
    • 为处 理动态 SQL语句中的占位符提供支持
  • 数据源模块

    • 提供了与第三方数据源集成的接口,位于数据源模块之中
  • 事务管理

    • My Batis 对数据库中的事务进行了抽象,其自身提供了相应的事务接口和简单实现。
  • 缓存模块

    • My Batis 中提供了一级缓存和二级缓存
    • MyBatis 中自带的这两级缓存与 MyBatis 以 及整个应用是运行在同一个 川币4 中的,共享同一块堆内存
    • 如果这两级缓存中的数据 量较大, 则可能影响系统中其他功能的运行,所以当需要缓存大量数据时,优先考虑 使用 Redis、 Memcache 等缓存产品。
      MyBatis源码探究(一)_第2张图片
  • Binding 模块
    在调用 SqI Session 相应方法执行数据库操作时,需要指定映射文件中定义的 SQL 节点,如果出现拼写错误,我们只能在运行时才能发现相应的 异常。 为了尽早发现这种错误, MyBatis 通过 Binding 模块将用户自定义的 Mapper 接口映射配置文件关联起来,系统可以通过调用自定义 Mapper 接口中的方法执行相应 的 SQL 语句完成数据库操作,从而避免上述问题。
    值得读者注意的是,开发人员无须编写自定义 Mapper 接口的实现, MyBatis 会自动为其创建动态代理对象。在有些场景中,自定义 Mapper 接口可以完全代替映射配置文件, 但有的映射规则和 SQL 语句的定义还是写在映射配置文件中比较方便,例如动态 SQL 语句的定义。

核心处理层

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

  • 配置解析
    在 MyBatis 初始化过程中,会加载 mybatis-config.xml 配置文件、映射配置文件以及 Mapper 接口中的注解信息,解析后的配置信息会形成相应的对象并保存到 Configuration 对象中。例如,示例中定义的<resultMap>节点(即 ResultSet 的映射规则) 会被解析成 ResultMap 对象:示例中定义的<result>节点(即属性映射)会被解析成 ResultMapping 对象。 之后,利用该 Configuration 对象创建 Sq!SessionFactory 对象。 待 MyBatis 初始化之后,开发人员可以通过初始化得到 Sq!SessionFactory 创建 Sq!Session 对象并完成数据库操作。

  • SOL 执行
    拼凑 SQL 语句是一件烦琐且易出错的过程,为了将开发人员从这项枯燥无趣的工作中 解脱出来, MyBatis 实现动态 SQL 语句的功能,提供了多种动态 SQL 语句对应的节点, 例如,<where>节点、<if>节点、<foreach>节点等。通过这些节点的组合使用, 开发人 员可以写出几乎满足所有需求的动态 SQL 语句。 My Batis 中的 scripting 模块会根据用户传入的实参,解析映射文件中定义的动态 SQL 节点,并形成数据库可执行的 SQL 语句。之后会处理 SQL 语句中的占位符,绑定用 户传入的实参。

  • SOL 解析与 scripting 模块
    SQL 语句的执行涉及多个组件,其中比较重要的是 Executor、 StatementHandler、 ParameterHandler 和 R巳sultSetHandler。 Executor 主要负责维护一级缓存和二级缓存, 并提供事务管理的相关操作,它会将数据库相关操作委托给 StatementHandler 完成。 StatementHandler 首先通过 ParameterHandler 完成 SQL 语句的实参绑定,然后通过 java.sql.Statement 对象执行 SQL 语句并得到结果集,最后通过 ResultSetHandler 完成结 果集的映射,得到结果对象并返回。图 1-5 展示了 MyBatis 执行一条 SQL 语句的大致 过程。
    MyBatis源码探究(一)_第3张图片

  • 插件
    Mybatis 自身的功能虽然强大,但是并不能完美切合所有的应用场景,因此 MyBatis 提供了插件接口,我们可以通过添加用户自定义插件的方式对 MyBatis 进行扩展。用 户自定义插件也可以改变 Mybatis 的默认行为,例如,我们可以拦截 SQL 语句并对其 进行重写。由于用户自定义插件会影响 MyBatis 的核心行为,在使用自定义插件之前, 开发人员需要了解 MyBatis 内部的原理,这样才能编写出安全、高效的插件。

接口层

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

你可能感兴趣的:(数据库,mybatis,数据库,java)