MyBatis 工作原理
MyBatis 是一款基于 Java 的持久层框架,它通过 XML 或注解注解的方式将 SQL 语句与 Java 代码分离,简化了 JDBC 操作的复杂性。其核心原理是通过配置映射关系,将 SQL 执行结果与 Java 对象自动绑定,同时避免了手动编写 JDBC 代码(如 Connection
、Statement
、ResultSet
等)的繁琐流程。
MyBatis 工作原理核心步骤
1. 初始化阶段:加载配置并构建核心对象
MyBatis 启动时会加载所有配置信息,构建核心组件,为后续操作做准备。
- 加载配置文件:
- 读取全局配置文件(如
mybatis-config.xml
),包含数据库连接信息(数据源)、全局参数(如缓存策略、默认执行器类型)、类型别名、插件等。 - 读取映射文件(如
UserMapper.xml
)或通过@Select
等注解定义的 SQL 语句、参数映射、结果映射(ResultMap)等。
- 读取全局配置文件(如
- 构建核心对象:
SqlSessionFactory
:通过SqlSessionFactoryBuilder
解析配置文件,生成SqlSessionFactory
(单例,全局唯一),它是创建SqlSession
的工厂。Configuration
:全局配置对象,存储所有配置信息(数据源、映射语句、ResultMap 等),是 MyBatis 的“大脑”。
2. 执行阶段:通过 SqlSession 执行 SQL
当应用程序需要操作数据库时,通过 SqlSessionFactory
创建 SqlSession
,并通过它执行具体 SQL。
- 创建
SqlSession
:SqlSession
是 MyBatis 的会话对象,封装了数据库连接(Connection
),提供了增删改查(selectOne
、insert
等)方法,是与数据库交互的入口。SqlSession
内部依赖Executor
(执行器),负责实际的 SQL 执行逻辑。
- 获取 Mapper 接口代理对象:
- 开发者通常通过
SqlSession.getMapper(UserMapper.class)
获取 Mapper 接口的代理对象(MyBatis 动态生成)。 - 代理对象的作用:当调用 Mapper 接口的方法(如
userMapper.selectById(1)
)时,会触发 MyBatis 内部逻辑,定位到对应的 SQL 语句。
- 开发者通常通过
- 解析并执行 SQL:
- 参数处理:根据 Mapper 方法的参数(如
id=1
),结合映射文件中的parameterType
或注解,将参数转换为 SQL 所需的格式(如?
占位符的参数值)。 - 生成
BoundSql
:将映射文件中的 SQL 语句与参数结合,生成可执行的 SQL(如select * from user where id = ?
并绑定参数1
)。 - 执行器(
Executor
)执行 SQL:Executor
通过 JDBC 连接(Connection
)创建PreparedStatement
,执行 SQL 并获取ResultSet
。- MyBatis 提供多种执行器:
SIMPLE
(简单执行器,默认)、REUSE
(重用语句执行器)、BATCH
(批量执行器)。
- 参数处理:根据 Mapper 方法的参数(如
- 结果映射(ResultMap):
- 执行 SQL 后,
ResultSet
中的数据需要转换为 Java 对象(如User
)。 - MyBatis 根据映射文件中的
ResultMap
或resultType
,自动将列名与 Java 对象的属性名匹配(支持驼峰命名映射等规则),完成数据绑定。
- 执行 SQL 后,
3. 资源释放阶段
- 操作完成后,
SqlSession
需要关闭(sqlSession.close()
),释放数据库连接(回归连接池)。 - 若开启了事务,
SqlSession
还会处理事务提交(commit()
)或回滚(rollback()
)。
核心组件总结
组件 | 作用 |
---|---|
SqlSessionFactory | 工厂类,负责创建 SqlSession ,全局唯一,基于配置文件初始化。 |
SqlSession | 会话对象,封装数据库连接,提供 CRUD 方法,是与数据库交互的入口。 |
Executor | 执行器,SqlSession 内部依赖,负责实际执行 SQL(与 JDBC 交互)。 |
Mapper 接口 | 定义数据操作方法,通过代理对象关联映射文件中的 SQL 语句。 |
Mapper 映射文件 | 存储 SQL 语句、参数映射、结果映射(ResultMap),实现 SQL 与代码分离。 |
Configuration | 全局配置对象,存储所有配置信息(数据源、映射关系等)。 |
关键优势
- SQL 与代码分离:SQL 写在 XML 或注解中,便于优化和维护(尤其复杂 SQL)。
- 自动映射:无需手动处理
ResultSet
到 Java 对象的转换,减少冗余代码。 - 灵活的参数处理:支持多种参数类型(基本类型、对象、集合),通过
#{}
占位符防止 SQL 注入。 - 插件扩展:可通过插件(如分页插件、日志插件)增强功能(基于拦截器模式)。
通过以上流程,MyBatis 既保留了 SQL 编写的灵活性,又简化了 JDBC 操作的复杂性,成为 Java 持久层框架的主流选择之一。