MyBatis 介绍与入门配置
适合对象:第一次接触 MyBatis,想先把“它是什么、怎么跑起来、代码怎样调用 SQL”弄明白的同学。
官方参考:
1. MyBatis 解决什么问题?
如果只用原生 JDBC 操作数据库,通常要写很多重复代码:
- 获取数据库连接
- 创建
PreparedStatement - 给 SQL 设置参数
- 执行 SQL
- 从
ResultSet里取值 - 手动把一行数据封装成 Java 对象
- 关闭连接、语句、结果集
MyBatis 做的事情,可以简单理解为:
让 Java 方法和 SQL 语句建立对应关系,帮我们处理参数传递、SQL 执行和结果封装。
例如有一个 Employee 类:
1 | public class Employee { |
再有一张 employee 表。MyBatis 可以把下面这条 SQL 查询出来的数据,自动封装成 Employee 对象:
1 | select * from employee where id = ? |
这样,Java 代码就不用自己一列一列读取结果集了。
2. 引入 MyBatis 依赖
如果使用 Maven,可以引入 MyBatis、数据库驱动和测试依赖:
1 | <dependency> |
这几类依赖的作用是:
| 依赖 | 作用 |
|---|---|
org.mybatis:mybatis |
MyBatis 框架本身 |
com.mysql:mysql-connector-j |
MySQL JDBC 驱动,让 Java 能连接 MySQL |
junit-jupiter |
用测试方法演示数据库操作 |
如果换成其他数据库,比如 PostgreSQL 或 Oracle,只需要换成对应数据库的 JDBC 驱动。
3. MyBatis 的基本运行流程
MyBatis 入门时最重要的三个对象是:
| 对象 | 作用 |
|---|---|
SqlSessionFactoryBuilder |
读取配置,创建 SqlSessionFactory |
SqlSessionFactory |
创建 SqlSession 的工厂 |
SqlSession |
表示一次数据库会话,用它执行 SQL |
它们的关系可以这样理解:
1 | flowchart TD |
一句话概括:
先读取配置创建
SqlSessionFactory,再打开SqlSession,最后通过SqlSession找到 XML 里的 SQL 并执行。
4. 创建 SqlSessionFactory
MyBatis 官方文档中说,每个基于 MyBatis 的应用都以 SqlSessionFactory 为核心。常见写法如下:
1 | public SqlSessionFactory getSqlSessionFactory() throws IOException { |
这段代码做了三件事:
- 指定 MyBatis 全局配置文件:
mybatis-config.xml - 用
Resources.getResourceAsStream(resource)从 classpath 读取配置 - 用
SqlSessionFactoryBuilder构建SqlSessionFactory
可以把 SqlSessionFactory 理解成“数据库会话工厂”。后面每次要操作数据库,都从它这里打开一个 SqlSession。
5. 使用 SqlSession 直接执行 SQL
第一种调用方式是直接使用 SQL 语句的唯一标识:
1 |
|
"EmployeeMapper.selectEmployee" 由两部分组成:
1 | namespace + "." + SQL 的 id |
对应 XML 可以这样写:
1 | <mapper namespace="EmployeeMapper"> |
这表示:
| Java 调用内容 | XML 中对应位置 |
|---|---|
| EmployeeMapper | <mapper namespace="EmployeeMapper"> |
| selectEmployee | <select id="selectEmployee"> |
| 参数 1 | SQL 里的 #{id} |
所以这句 Java 代码:
1 | session.selectOne("EmployeeMapper.selectEmployee", 1); |
会找到这条 SQL:
1 | select * from employee where id = #{id} |
然后把参数 1 传给 #{id}。
6. 更常用的 Mapper 接口方式
直接写字符串能运行,但开发中更推荐 Mapper 接口方式。
先定义接口:
1 | public interface EmployeeMapper { |
再让 XML 的 namespace 对应接口全类名,SQL 的 id 对应接口方法名:
1 | <mapper namespace="com.bytepro.mapper.EmployeeMapper"> |
调用时这样写:
1 |
|
接口、XML、SQL 的对应关系如下:
1 | flowchart LR |
接口方式的好处是:
- 方法名有代码提示
- 参数和返回值类型清楚
- 少写字符串,减少拼错 SQL 标识的机会
- 调用方式更像普通 Java 方法
7. SqlSession 用完要关闭
SqlSession 代表一次数据库会话,它不是线程安全的,也不应该长期共享。使用完后要关闭:
1 | SqlSession session = factory.openSession(); |
也可以使用 Java 的 try-with-resources:
1 | try (SqlSession session = factory.openSession()) { |
这样写的目的都是一样的:保证数据库会话能被正确释放。
8. 增删改为什么要 commit?
查询只是读取数据,一般不需要手动提交事务。新增、修改、删除会改变数据库数据,需要提交:
1 | Long result = mapper.insertEmployee(employee); |
如果用下面这种方式打开会话:
1 | SqlSession session = factory.openSession(); |
默认不是自动提交。执行 insert、update、delete 后,如果没有调用 session.commit(),修改可能不会真正保存到数据库。
9. 这一篇先记住什么?
- MyBatis 用来建立 Java 方法和 SQL 语句之间的映射关系。
SqlSessionFactoryBuilder读取配置,创建SqlSessionFactory。SqlSessionFactory用来打开SqlSession。SqlSession用来执行 SQL,用完必须关闭。- Mapper 接口方式比字符串方式更常用。
- XML 中的
namespace + id决定 Java 代码能找到哪条 SQL。