
MyBatis 是 Java 生态中非常著名的一款 ORM 框架,目前在一线互联网大厂中应用广泛,MyBatis已经成为了一个必会框架。
MyBatis工作原理,如下图所示 :

上面中流程就是MyBatis内部核心流程,一共会经历8大步骤,下面我会详解8大步骤。
第一步:读取MyBatis的配置文件
MyBatis-config.xml为MyBatis的全局配置文件,用于配置数据库连接信息。
如下所示:
<configuration>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="sqlMapper/userMapper.xml"/>
</mappers>
</configuration>
mapper.xml:sql的映射文件,配置了操作数据库的sql语句,此文件需在config.xml中加载。
比如:加载用户映射信息UserMapper.xml。
<mappers> <mapper resource="sqlMapper/userMapper.xml"/> </mappers>
第二步:加载映射文件
SQL的映射文件,配置了操作数据库的SQL语句,需要在MyBatis配置文件MyBatis-config.xml中加载。
MyBatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。
如下所示:
<mappers> <mapper resource="sqlMapper/userMapper.xml"/> </mappers>
MyBatis-config.xml 加载用户表,映射文件为:UserMapper.xml。
第三步:构造会话工厂
通过MyBatis的环境配置信息构建会话工厂SqlSessionFactory,用来开启SqlSession。
SqlSessionFactory是MyBatis框架中的一个接口,主要负责MyBatis框架初始化操作及为开发人员提供SqlSession对象。
它有两个实现类:DefaultSqlSessionFactory和SqlSessionManager,其中SqlSessionManager已被废弃。
在Mybtis初始化的过程中首先会读取MyBatis的核心配置文件,一般创建SqlSessionFactory的代码如下:
//使用 SqlSessionFactoryBuilder 构建 SqlSessionFactory SqlSessionFactory SqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
SqlSessionFactoryBuilder通过Configuration对象生成SqlSessionFactory,用来开启SqlSession。
第四步:创建会话对象
由会话工厂创建SqlSession对象,该对象中包含了执行SQL语句的所有方法,SqlSession对象完成和数据库的交互。
SqlSession提供select、insert、update、delete方法,用于完成和数据库的交互。
第五步:Executor执行器
MyBatis底层定义了一个Executor接口来操作数据库,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。
Execute执行器起到至关重要的作用,它是真正执行Java与数据库交互的东西,参与了整个SQL查询执行过程中。
主要有三种执行器:
- 简易执行器SIMPLE(不配置就是默认执行器);
- REUSE是一种重用预处理语句;
- BATCH批量更新批量专用处理器
public enum ExecutorType {
SIMPLE, REUSE, BATCH
}
第六步:MappedStatement对象
在Executor接口的执行方法中有一个MappedStatement类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等信息。
在Executor中doQuery()方法返回了封装的结果集,如下所示:
@Override
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
Statement stmt = null;
try {
Configuration configuration = ms.getConfiguration();
StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
stmt = prepareStatement(handler, ms.getStatementLog());
return handler.<E>query(stmt, resultHandler);
} finally {
closeStatement(stmt);
}
}
第七步:输入参数映射
输入映射,是在映射文件中通过parameterType指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型。
假设现在有个比较复杂的查询需求:完成用户信息的综合查询,需要传入查询条件很复杂。
可能包括:用户信息、其它信息,比如:商品、订单等,那么我们单纯的传入一个User就不行了,所以首先我们得根据查询条件,自定义一个新的pojo,在这个pojo中包含所有的查询条件。
package com.MyBatis.entity;
public class UserQueryVo {
//在这里添加所需要的查询条件
//用户查询条件,这里假设一个User就已经够了
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
//可以包装其他的查询条件,比如订单、商品等
//......
}
第八步:输出结果映射
使用resultType进行输出映射,输出结果类型可以是Map、List等集合类型,只有查询出来的列名和POJO中的属性名一致,该列才可以映射成功。
拆解,后续我将重点分析其核心源码,这样先全局再局部,这样更有利于掌握其核心原理实现,希望这个框架系列能对你有所用。
mikechen睿哥
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。