本文来说下关于Mybatis的几个问题

文章目录

  • 概述
  • 持久层的那些事
    • 什么是 JDBC
    • JDBC 原理
    • 什么是 Mybatis
    • Mybatis 与 JDBC 的关系
  • Mybatis 关键词说明
  • Mybatis 架构设计
    • 架构图
    • 基础支持层
    • 核心处理层
    • 接口层
  • 问题答疑
    • .xml 文件定义 Sql 语句如何解析
    • Mapper 接口的存储与实现
    • Mybatis Sql 的执行过程
    • Mybatis 中分页如何实现
  • 本文小结

概述

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

本文将和大家分享以下关于Mybatis的知识与内容

  • Mybatis 与 JDBC 的关系
  • .xml 文件定义 SQL 语句如何解析
  • Mybatis 中 Mapper 接口的存储与实现
  • Mybatis SQL 的执行过程
  • Mybatis 中分页如何实现

本次分享内容依据 Mybatis-3-3.4.x 源码


持久层的那些事

什么是 JDBC

JDBC(JavaDataBase Connectivity)就是 Java 数据库连接, 说的直白点就是 使用 Java 语言操作数据库。本来我们是通过控制台或客户端操作的数据库, JDBC 是用 Java 语言来发送 SQL 语句。


JDBC 原理

最初 SUN 公司希望提供一套 能够适用所有数据库的 API, 但是在实际操作中却发现这是项基本不可能完成的任务。

因为各个厂商所提供的 数据库差异实在太大, 所以 SUN 公司与数据库厂商讨论出的就是:由 SUN 公司提供出一套访问数据库的规范 API, 并提供相对应的连接数据库协议标准, 然后各厂商根据规范提供一套访问自家数据库的 API 接口。

最终:SUN 公司提供的规范 API 称之为 JDBC, 各厂商提供的自家数据库 API 接口称之为 驱动


什么是 Mybatis

Mybatis 是一款优秀的 ORM(持久层)框架,使用 Java 语言 编写。前身是 apache 的一个开源项目 iBatis,2010 年迁移到 google code 并正式改名为 Mybatis。

ORM 持久层 指的是 : 将业务数据存储到磁盘,也具备长期存储能力,只要磁盘不损坏,如果在断电情况下,重启系统仍然可以读取数据


Mybatis 与 JDBC 的关系

在没有持久层框架之前, 想要代码中操作数据库都必须通过 JDBC 来操作, 接下来一个例子来说明两者之间的关系。

JDBC 操作数据库

相信大家都在实际项目中使用过 Mybatis, 可以联想一下, 平常我们工作中, 是否做过以下事情:

  • 是否装载过数据库驱动?
  • 是否从驱动中获取数据库连接?
  • 是否创建过执行 SQL 的 Statement?
  • 是否自行将数据库返回结果转换成 Java 对象?
  • 是否关闭过 finally 块中的三个对象?

看到上面的灵魂拷问, 就可以对本次分享的第一个问题作出解答:

Mybatis 针对 JDBC 中重复操作做了封装, 同时扩展并优化部分功能


Mybatis 关键词说明

SqlSession

负责执行 select、insert、update、delete 等命令, 同时负责获取映射器和管理事务; 其底层封装了与 JDBC 的交互, 可以说是 mybatis 最核心的接口之一。

SqlSessionFactory

负责创建 SqlSession 的工厂, 一旦被创建就应该在应用运行期间一直存在, 不需要额外再进行创建。

SqlSessionFactoryBuilder

主要是负责创建 SqlSessionFactory 的构造器类, 其中使用到了构建者设计模式; 仅负责创建 SqlSessionFactory。

Configuration

Mybatis 最重要的配置类, 没有之一, 存储了大量的对象配置, 可以看源码感受一下。

MappedStatement

MappedStatement 是保存 SQL 语句的数据结构, 其中的类属性都是由解析 .xml 文件中的 SQL 标签转化而成。

Executor

SqlSession 对象对应一个 Executor, Executor 对象作用于 增删改查方法 以及 事务、缓存 等操作。

ParameterHandler

Mybatis 中的 参数处理器, 类关系比较简单。

StatementHandler

StatementHandler 是 Mybatis 负责 创建 Statement 的处理器, 根据不同的业务创建不同功能的 Statement

ResultSetHandler

ResultSetHandler 是 Mybatis 负责将 JDBC 返回数据进行解析, 并包装为 Java 中对应数据结构的处理器。

Interceptor

Interceptor 为 Mybatis 中定义公共拦截器的接口, 其中定义了相关实现方法。


Mybatis 架构设计

架构图


基础支持层

反射模块

反射在 Java 中的应用可以说是相当广泛了, 同时也是一把双刃剑。 Mybatis 框架本身 封装出了反射模块, 提供了比原生反射更 简洁易用的 API 接口, 以及对 类的元数据增加缓存, 提高反射的性能。

类型转换

类型转换模块最重要的功能就是在为 SQL 语句绑定实参时, 将 Java 类型转为 JDBC 类型, 在映射结果集时再由 JDBC 类型转为 Java 类型。另外一个功能就是提供别名机制, 简化了配置文件的定义。

日志模块

日志对于系统的作用不言而喻, 尤其是测试、生产环境上查看信息及排查错误等都非常重要。主流的日志框架包括 Log4j、Log4j2、S l f4j 等, Mybatis 的日志模块作用就是 集成这些日志框架。

资源加载

Mybatis 对类加载器进行了封装, 用来确定类加载器的使用顺序, 用来记载类文件以及其它资源文件, 感兴趣可以参考 ClassLoaderWrapper。

解析器模块

解析器模块主要提供了两个功能, 一个是封装了 XPath 类, 在 Mybatis 初始化时解析 Mybatis-config.xml 配置文件以及映射配置文件提供功能, 另一点就是处理动态 SQL 语句的占位符提供帮助。


核心处理层

配置解析

在 Mybatis 初始化时, 会加载 Mybatis-config.xml 文件中的配置信息, 解析后的配置信息会 转换成 Java 对象添加到 Configuration 对象。

SQL 解析

大家如果手动拼写过复杂 SQL 语句, 就会明白会有多痛苦。Mybatis 提供出了动态 SQL, 加入了许多判断循环型标签, 比如 : if、where、foreach、set 等, 帮助开发者节约了大量的 SQL 拼写时间。

SQL 解析模块的作用就是将 Mybatis 提供的动态 SQL 标签解析为带占位符的 SQL 语句, 并在后期将实参对占位符进行替换。

SQL 执行

SQL 的执行过程涉及几个比较重要的对象, Executor、StatementHandler、ParameterHandler、ResultSetHandler

Executor 负责维护 一级、二级缓存以及事务提交回滚操作, 举个查询的例子, 查询请求会由 Executor 交给 StatementHandler 完成。

StatementHandler 通过 ParameterHandler 完成 SQL 语句的实参绑定, 通过 java.sql.Statement 执行 SQL 语句并拿到对应的 结果集映射。

最后交由 ResultSetHandler 对结果集进行解析, 将 JDBC 类型转换为程序自定义的对象。

插件

插件模块是 Mybatis 提供的一层扩展, 可以针对 SQL 执行的四大对象进行 拦截并执行自定义插件。

插件编写需要很熟悉 Mybatis 运行机制, 这样才能控制编写的插件安全、高效。


接口层

接口层只是 Mybatis 提供给调用端的一个接口 SqlSession, 调用端在进行调用接口中方法时, 会调用核心处理层相对应的模块来完成数据库操作


问题答疑

.xml 文件定义 Sql 语句如何解析

Mybatis 在创建 SqlSessionFactory 时, XMLConfigBuilder 会解析 Mybatis-config.xml 配置文件

Mybatis 相关解析器

Mybatis 解析器模块中定义了相关解析器的抽象类 BaseBuilder, 不同的子类负责实现解析不同的功能, 使用了 Builder 设计模式


XMLConfigBuilder 负责解析 mybatis-config.xml 配置文件

XMLMapperBuilder 负责解析业务产生的 xxxMapper.xml

mybatis-config.xml 解析

XMLConfigBuilder 解析 mybatis-config.xml 内容参考代码 :


XMLConfifigBuilder#parseConfiguration() 方法将 mybatis-config.xml 中定义的标签进行相关解析并填充到 Configuration 对象中。

xxxMapper.xml 解析

XMLConfifigBuilder#mapperElement() 中解析配置的 mappers 标签, 找到具体的 .xml 文件, 并将其中的 select、insert、update、delete、resultMap 等标签解析为 Java 中的对象信息

具体解析 xxxMapper.xml 的对象为 XMLMapperBuilder, 具体的解析方法为 parse()


到这里就可以对当前问题作出答复了

Mybatis 创建 SqlSessionFactory 会解析 mybatis-config.xml, 然后 解析 configuration 标签下的子标签, 解析 mappers 标签时, 会根据相关配置读取到 .xml 文件, 继而解析 .xml 中各个标签。

具体的 select、insert、update、delete 标签定义为 MappedStatement 对象, .xml 文件中的其余标签也会根据不同映射解析为 Java 对象。

MappedStatement

这里重点说明下 MappedStatement 对象, 一起看一下类中的属性和 SQL 有何关联呢


MappedStatement 对象中 提供的属性与 .xml 文件中定义的 SQL 语句 是能够对应上的, 用来 控制每条 SQL 语句的执行行为


Mapper 接口的存储与实现

在平常我们写的 SSM 框架中, 定义了 Mapper 接口与 .xml 对应的 SQL 文件, 在 Service 层直接注入 xxxMapper 就可以了。

也没有看到像 JDBC 操作数据库的操作, Mybatis 在中间是如何为我们省略下这些重复繁琐的操作呢。

这里使用 Mybatis 源码中的测试类进行验证, 首先定义 Mapper 接口, 省事直接注解定义 SQL。


这里使用 SqlSession 来获取 Mapper 操作数据库, 测试方法如下

创建 SqlSession

#1 从 SqlSessionFactory 中打开一个 新的 SqlSession

获取 Mapper 实例

#2 就存在一个疑问点, 定义的 AutoConstructorMapper 明明是个接口, 为什么可以实例化为对象?

动态代理方法调用

#3 通过创建的对象调用类中具体的方法, 这里具体聊一下 #2 操作

SqlSession 是一个接口, 有一个 默认的实现类 DefaultSqlSession, 类中包含了 Configuration 属性

Mapper 接口的信息以及 .xml 中 SQL 语句是在 Mybatis 初始化时添加 到 Configuration 的 MapperRegistry 属性中的


#2 中的 getMapper 就是从 MapperRegistry 中获取 Mapper

看一下 MapperRegistry 的类属性都有什么

config 为 保持全局唯一 的 Configuration 对象引用。knownMappers 中 Key-Class 是 Mapper 对象, Value-MapperProxyFactory 是通过 Mapper 对象衍生出的 Mapper 代理工厂。

再看一下 MapperProxyFactory 类的结构信息


mapperInterface 属性是 Mapper 对象的引用, methodCache 的 key 是 Mapper 中的方法, value 是 Mapper 解析对应 SQL 产生的 MapperMethod。

关于Mybatis的几个问题相关推荐

  1. mybatis查询报错:com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from string

    mybatis查询报错: com.mysql.cj.exceptions.DataConversionException: Cannot determine value type from strin ...

  2. MyBatis的插入后获得主键的方式

    需求: 使用MyBatis往MySQL数据库中插入一条记录后,需要返回该条记录的自增主键值. 方法: 在mapper中指定keyProperty属性,示例如下: <insert id=" ...

  3. mybatis使用注解开发

    mybatis使用注解开发 面向接口编程 在之前我们是通过面向对象编程,但是在真正开发的时候我们会选择面向接口编程. 根本原因 : 解耦 , 可拓展 , 提高复用 , 分层开发中 , 上层不用管具体的 ...

  4. mybatis ResultMap

    ResultMap 解决属性名和字段的名称不一致的问题. 查询为null的问题 创建java实体类: public class User {private int id; //idprivate St ...

  5. mybatis配置文件解析

    mybatis配置文件解析 mybatis核心配置文件`mybatis-config.xml文件. mybatis的配置文件包含了会深深影响mybatis行为的设置和属性信息. 能配置的内容: con ...

  6. mybatis CRUD操作

    mybatis CRUD操作 select select标签是mybatis最常用的标签之一. select语句有很多属性可以详细的配置每一天sql语句. id 命名空间唯一的标识. 接口中的方法名与 ...

  7. java mybatis基础

    java mybatis基础 1.1 什么是mybatis? mybatis是一个优秀的持久层框架. 避免几乎所有的JDBC代码和手动设置参数以及获取结果集的过程. 可以使用简单的xml或者注解来配置 ...

  8. mybatis的资源过滤错误及xml文件编码错误

    mybatis 解决maven项目内资源过滤的问题 写的配置文件无法被导出或者生效的问题. 解决方案: <build><resources><resource>&l ...

  9. Mybatis传递多个参数的4种方式

    现在大多项目都是使用Mybatis了,但也有些公司使用Hibernate.使用Mybatis最大的特性就是sql需要自己写,而写sql就需要传递多个参数.面对各种复杂的业务场景,传递参数也是一种学问. ...

  10. SpringBoot (五) :SpringBoot整合mybatis

    说在前面 mybatis刚开始使用的时候比较麻烦,需要各种配置文件.实体类.dao层映射关联.还有一大推其它配置.初期开发了generator可以根据表结果自动生产实体类.配置文件和dao层代码,可以 ...

最新文章

  1. 帮朋友招聘赴北京微软ASP.NET开发工程师
  2. Spring Boot骚操作-多数据源Service层封装
  3. java.util类,GitHub - yutaolian/JavaUtils: 总结的一些Java常用的util类
  4. DWZ关闭navTab后刷新指定的navTab
  5. Angular Package Format (APF) v12.0 介绍
  6. 美国东北大学khoury计算机学院,2021年美国东北大学计算机研究生专业有哪些?入学要求高吗?...
  7. 蜗轮蜗杆计算软件_正确的组装蜗轮蜗杆减速机至关重要
  8. c#中索引器是什么_C#中的索引器
  9. 中兴F412光猫超级密码破解、破解用户限制、关闭远程控制、恢复路由器拨号
  10. command对象提供的3个execute方法是_Python:3分钟看懂,基于 Psycopg2 的 PostgreSQL 操作指南!
  11. qt 处理oracle事务,qt调用oracle存储过程,该怎么处理(2)
  12. 无线通信设备安装工程概预算编制_深圳宝安不锈钢厨房设备安装工程
  13. 每个国家对应的语言Locale和国家代码对照表(国际化支持)
  14. 火星坐标 C语言,坐标
  15. 自然语言推断:微调BERT
  16. 解决无法删除文件夹的情况
  17. Clickhouse的 MySQL ELT和interval 功能等同实现 roundDown
  18. redis之AOF和RDB持久化
  19. 20个非常有用的Python单行代码
  20. 哪个选项不是python文件打开的合法模式组合_下面代码的输出结果是( ):

热门文章

  1. 基於tiny4412的Linux內核移植--- 中斷和GPIO學習(2)
  2. Unity 利用NGUI做屏幕分辨率适配+学习UIDraggablePanel的使用
  3. U盘PE安装windows7 方法
  4. 《构建之法》(第四、十七章)读书笔记
  5. C#Panel 控件的使用
  6. 分布式事务 - 梁飞的博客 - ITeye博客
  7. 1-2 输出N个数的平方和立方值
  8. HDU2012 素数判定
  9. 跨平台开源通讯组件elastic communication
  10. jsp和mysql乱码