前言
在国内,mybatis 目前的流行程度不用多说,绝大多数公司的技术栈都有它。mybatis 作为一个轻量级的持久层框架,比起老牌 orm 框架 Hibernate 和 spring 家族的 spring jpa,mybatis 并不透明化 dao 层,而是关注于 java 方法与 sql 的映射,大大简化了用 java 原生 api 进行数据库操作的繁琐。比起掌握 orm 框架所需的额外学习成本,mybaits 的学习成本很低:最终掌控 sql 的还是程序员。
搭建一个 mybatis 框架,需要有这几个部分:
- 配置
- sql
- 对 sql 对应的接口方法
所以 mybatis 的执行流程就呼之欲出了:读取配置,将接口中的方法与 sql 关联。调用方法,执行 sql,完成查询。看起来简单,那么,这次我们就尝试搭建一个简单的 mybaits,来理解其工作的大体流程。
本文代码
导航
流程概述
为了方(偷)便(懒)起见,本文这次我们使用 java api 进行 mybatis 的配置:
1 | public static void main(String[] args) throws IOException { |
我们可以看到,去除类工厂,mybatis 有这些关键的对象:
- Configuration:包含了数据源、事务管理、mappers 等信息
- SqlSession:获取 mapper 的代理对象
- mapper 代理对象:进行数据库操作
那么,我们极简的 mybaits 大体框架也可以出来了:
1 | public static void main(String[] args) { |
涉及的类与方法:
- Configuration
- Configuration(DataSource dataSource)
- configuration.addMapper(Class mapper)
- SqlSession
- SqlSession(Configuration configuration)
- getMapper(Class type)
- MapperProxy:mapper 代理
获取 mapper
Configuration 中用 map 来保存 mapper 及其代理,而 SqlSession 通过调用 Configuration 中的方法,返回代理:
1 | public class Configuration { |
调用 mapper 方法
MapperProxy 采用了 java 反射,通过注解来获得 sql 及其参数:
1 | public class MapperProxy<T> implements InvocationHandler { |
执行 sql 语句
注意到 SqlSession 的 select 实际上调用了 executor 的 query 方法。也就是说,真正执行 sql 语句的,其实是 executor:
1 | public class Executor { |
至此,一个极简 mybaits 的流程就大体介绍完了。而真正的 mybatis,包含了许多模块: