MyBatis基础教程:Java持久层框架入门
大家好,我是一名开源项目维护者,也经常给刚入行的开发者做技术培训。今天我想和大家聊聊 MyBatis —— 一个在 Java 后端开发中非常常用的持久层框架。
你可能会问:“我是个零基础小白,连数据库都没怎么碰过,能学会吗?”当然可以!我当初学的时候,也是从“什么是数据库连接”开始的。这篇教程就是专门为像你这样的初学者准备的,我会用最直白的语言、最简单的例子,带你一步步上手 MyBatis。
📝 小提示:虽然本文讲的是 Java 技术,但文末我会告诉你为什么掌握它对你的 简历 很有帮助,甚至对学 Python 或 JavaScript 的朋友也有启发!
一、MyBatis 是什么?为什么要学它?
简单说:MyBatis 是一个帮助 Java 程序和数据库“对话”的工具。
想象一下:你想把用户注册信息(比如用户名、密码)存到数据库里。不用框架的话,你需要写一大堆代码来:
- 连接数据库
- 拼接 SQL 语句
- 处理各种异常
- 把查询结果一行行转成 Java 对象
这不仅繁琐,还容易出错。
而 MyBatis 做的事就是:帮你自动完成这些重复劳动,让你专注业务逻辑。
和 Python / JavaScript 有什么关系?
你可能更熟悉 Python(比如用 Django/Flask)或 JavaScript(比如用 Node.js + Sequelize)。它们都有类似的“ORM”或“数据库映射”工具:
- Python 的 SQLAlchemy、Django ORM
- JavaScript 的 Sequelize、Prisma
MyBatis 就是 Java 世界里的这类工具之一。虽然它不是完全的 ORM(后面会解释),但作用类似:让数据库操作变得简单、安全、可维护。
所以,即使你现在主攻 Python 或 JS,了解 MyBatis 也能帮你理解“不同语言如何解决同一个问题”,这对拓宽技术视野、写好 简历(尤其是想转 Java 后端岗位时)非常有用!
二、环境准备:5 分钟搭好开发环境
我们要用最轻量的方式跑通第一个 MyBatis 程序。你需要以下工具:
| 工具 | 版本建议 | 作用 |
|---|---|---|
| JDK | 8 或 11 | 运行 Java 程序 |
| Maven | 3.6+ | 管理项目依赖 |
| IDE | IntelliJ IDEA(社区版免费)或 VS Code | 写代码 |
| 数据库 | MySQL 5.7+ 或 H2(内存数据库) | 存储数据 |
💡 新手友好选择:如果你不想装 MySQL,可以用 H2 数据库——它是一个纯 Java 的内存数据库,无需安装,适合学习!
步骤 1:创建 Maven 项目
打开终端,执行:
mkdir mybatis-demo
cd mybatis-demo
然后创建标准 Maven 目录结构:
mybatis-demo/
├── src/
│ └── main/
│ ├── java/
│ └── resources/
└── pom.xml
步骤 2:编辑 pom.xml 添加依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>mybatis-demo</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- MyBatis 核心 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<!-- 使用 H2 内存数据库(免安装!) -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.2.224</version>
</dependency>
<!-- 日志输出(方便调试) -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
</dependency>
</dependencies>
</project>
步骤 3:验证环境
在 src/main/java 下创建 Hello.java:
public class Hello {
public static void main(String[] args) {
System.out.println("Java 环境 OK!");
}
}
运行:
mvn compile exec:java -Dexec.mainClass="Hello"
如果看到输出 Java 环境 OK!,说明环境准备成功!
三、核心概念:用大白话讲清楚 MyBatis
1. 什么是“持久层”?
- 持久层 = 和数据库打交道的那一层代码
- 比如:保存用户、查询订单、删除商品……这些操作都属于持久层
2. MyBatis 的三大核心组件
| 组件 | 作用 | 类比理解 |
|---|---|---|
SqlSessionFactory |
创建数据库会话的“工厂” | 像是“数据库连接的总开关” |
SqlSession |
一次数据库会话,用来执行 SQL | 像是“和数据库聊天的窗口” |
| Mapper 接口 + XML | 定义 SQL 语句和 Java 方法的映射 | 像是“翻译官”:把 Java 方法转成 SQL |
3. MyBatis vs 全自动 ORM(如 Hibernate)
| 特性 | MyBatis | Hibernate(全自动 ORM) |
|---|---|---|
| SQL 控制 | 手写 SQL,完全可控 | 自动生成 SQL,黑盒 |
| 学习曲线 | 较平缓 | 较陡 |
| 性能调优 | 容易(直接改 SQL) | 困难(需懂内部机制) |
| 适合场景 | 需要精细控制 SQL 的项目 | 快速开发、CRUD 为主的项目 |
✅ 对新手建议:先学 MyBatis!因为你能看到每一行 SQL,更容易理解数据库原理。
四、实战项目:实现一个“用户管理系统”
我们将实现一个最简单的功能:添加用户 + 查询所有用户。
步骤 1:创建数据库表(H2 自动创建)
在 src/main/resources 下创建 schema.sql:
CREATE TABLE user (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100)
);
步骤 2:编写 MyBatis 配置文件
创建 src/main/resources/mybatis-config.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;INIT=RUNSCRIPT FROM 'classpath:schema.sql'"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
🔍 注意:
INIT=RUNSCRIPT FROM 'classpath:schema.sql'表示启动时自动执行建表脚本。
步骤 3:定义 Java 实体类
创建 src/main/java/User.java:
public class User {
private int id;
private String name;
private String email;
// 必须提供 getter/setter(MyBatis 通过它们赋值)
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
@Override
public String toString() {
return "User{id=" + id + ", name='" + name + "', email='" + email + "'}";
}
}
步骤 4:编写 Mapper 接口和 XML
创建 src/main/java/UserMapper.java:
import java.util.List;
public interface UserMapper {
void insertUser(User user);
List<User> findAllUsers();
}
创建 src/main/resources/UserMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="UserMapper">
<insert id="insertUser" parameterType="User">
INSERT INTO user (name, email) VALUES (#{name}, #{email})
</insert>
<select id="findAllUsers" resultType="User">
SELECT * FROM user
</select>
</mapper>
📌 关键点:
namespace必须和接口全名一致(这里简化用了短名,实际建议用全限定名)#{name}会自动从 User 对象中取name属性resultType="User"表示查询结果自动映射到 User 类
步骤 5:编写主程序测试
创建 src/main/java/Main.java:
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
// 1. 读取配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 2. 创建 SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 3. 获取 SqlSession
try (SqlSession session = sqlSessionFactory.openSession()) {
// 4. 获取 Mapper 接口
UserMapper mapper = session.getMapper(UserMapper.class);
// 5. 插入用户
User user1 = new User();
user1.setName("张三");
user1.setEmail("zhangsan@example.com");
mapper.insertUser(user1);
User user2 = new User();
user2.setName("李四");
user2.setEmail("lisi@example.com");
mapper.insertUser(user2);
// 6. 提交事务(重要!)
session.commit();
// 7. 查询所有用户
List<User> users = mapper.findAllUsers();
System.out.println("所有用户:");
for (User u : users) {
System.out.println(u);
}
}
}
}
步骤 6:运行!
mvn compile exec:java -Dexec.mainClass="Main"
预期输出:
所有用户:
User{id=1, name='张三', email='zhangsan@example.com'}
User{id=2, name='李四', email='lisi@example.com'}
🎉 恭喜!你已经完成了第一个 MyBatis 程序!
五、新手常见问题解答(FAQ)
Q1:为什么插入后查不到数据?
原因:忘记调用 session.commit()。MyBatis 默认开启事务,不提交就不会真正写入数据库。
✅ 解决:在 insert/update/delete 后加 session.commit()。
Q2:报错 “There is no getter for property named ‘xxx’”
原因:Java Bean 缺少对应的 getter 方法,或属性名拼写错误。
✅ 解决:
- 检查
User类是否有getXxx()方法 - 确保 XML 中
#{xxx}的名字和 Java 属性名一致(区分大小写)
Q3:能不能不用 XML,直接用注解?
可以!例如:
public interface UserMapper {
@Insert("INSERT INTO user (name, email) VALUES (#{name}, #{email})")
void insertUser(User user);
@Select("SELECT * FROM user")
List<User> findAllUsers();
}
但复杂 SQL(如多表关联)仍推荐用 XML,更清晰、易维护。
Q4:MyBatis 能防止 SQL 注入吗?
能! 只要你用 #{}(预编译),不要用 ${}(字符串拼接)。
- ✅ 安全:
WHERE name = #{name} - ❌ 危险:
WHERE name = '${name}'(会被注入)
六、学习建议与下一步
为什么 MyBatis 对简历很重要?
- 几乎所有 Java 后端岗位都要求熟悉 MyBatis 或 MyBatis-Plus
- 在 GitHub 上,MyBatis 相关项目超 20k stars,生态成熟
- 掌握它意味着你能独立完成“数据持久化”这一核心模块
💼 简历技巧:即使你主攻 Python/JS,也可以写:“了解 Java 生态,熟悉 MyBatis 数据持久化原理”,展现技术广度。
下一步学什么?
| 方向 | 推荐内容 |
|---|---|
| 深入 MyBatis | 动态 SQL(<if>, <foreach>)、缓存机制、插件开发 |
| 简化开发 | 学习 MyBatis-Plus(国产增强版,自动生成 CRUD) |
| 整合 Spring | 学习 Spring Boot + MyBatis(企业级标配) |
| 对比学习 | 用 Python 的 SQLAlchemy 或 JS 的 Prisma 实现同样功能,加深理解 |
我的避坑指南
- 不要死记 XML 语法:先跑通,再查文档
- 日志很重要:加 logback 依赖,看 MyBatis 实际执行的 SQL
- 从小项目开始:别一上来就搞分页、多数据源,先把增删改查玩熟
结语
我当初学 MyBatis 时,也被 SqlSession、Mapper 这些概念绕晕过。但只要你动手写一遍上面的代码,就会发现:它其实就是在帮我们“偷懒”——把重复的数据库操作自动化了。
无论你未来是做 Java、Python 还是 JavaScript 开发,理解“如何高效、安全地操作数据库”都是核心能力。希望这篇教程能成为你技术路上的一块垫脚石。
现在,去运行你的第一个 MyBatis 程序吧! 有问题欢迎留言讨论。
作者:一位爱写文档的开源维护者
字数:约 3690 字
最后更新:2024 年
延伸思考:当你用 Python 写 Flask 时,是否也想过“SQLAlchemy 背后是怎么把对象转成 SQL 的?”——其实原理和 MyBatis 异曲同工。技术的本质,往往相通。

评论 0