MyBatis基础教程:Java持久层框架入门
大家好,我是一名工作5年的后端开发工程师。今天写这篇教程,是因为我当初学MyBatis的时候踩过太多坑——文档太抽象、概念太绕、代码一跑就报错。现在回头看看,其实它没那么难!只要用对方法,零基础也能快速上手。
这篇文章会用最通俗的语言,带你从零开始认识MyBatis,并完成一个简单的实战项目。即使你连“持久层”是什么都不知道,也没关系,我们一步步来。
📌 小提示:虽然本文讲的是Java框架,但我会在合适的地方提到Python作为对比,帮助你理解不同语言生态下的工具差异。
一、MyBatis 是什么?能用来做什么?
简单说,MyBatis 是一个 Java 的“数据库翻译官”。
- 你的 Java 程序不能直接和数据库(比如 MySQL)对话。
- 数据库只听得懂 SQL(结构化查询语言)。
- MyBatis 的作用就是:把 Java 对象自动转换成 SQL 语句,再把数据库返回的结果转回 Java 对象。
举个生活化的例子:
想象你要点外卖:
- 你(Java程序)想吃“宫保鸡丁”
- 但餐厅厨房(数据库)只认菜谱(SQL)
- MyBatis 就是那个服务员:你告诉它“我要宫保鸡丁”,它跑去厨房说“来一份宫保鸡丁”,然后把做好的菜端回来给你
和 Python 的对比
在 Python 中,你可能用过 SQLAlchemy 或 Django ORM,它们的作用和 MyBatis 类似——都是帮程序和数据库“搭桥”。只不过 MyBatis 更偏向“手动写 SQL + 自动映射”,而 Django ORM 更偏向“完全自动生成 SQL”。
二、环境准备:5分钟搭建开发环境
我们需要以下工具(全是免费的):
| 工具 | 用途 | 安装建议 |
|---|---|---|
| JDK 8+ | 运行 Java | 推荐 OpenJDK 11 |
| Maven | 项目依赖管理 | 官网下载或 IDE 自带 |
| IntelliJ IDEA(社区版) | 代码编辑器 | 免费,功能强大 |
| MySQL 5.7+ | 数据库 | 可用 Docker 快速启动 |
步骤 1:创建 Maven 项目
打开 IDEA → New Project → Maven → 勾选 “Create from archetype” → 选择 maven-archetype-quickstart
步骤 2:添加 MyBatis 依赖
在 pom.xml 中加入以下代码:
<dependencies>
<!-- MyBatis 核心库 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
💡 避坑指南:很多人卡在驱动版本上。如果你用 MySQL 8.x,请务必用
mysql-connector-java8.0+,否则会连不上!
三、核心概念:3个关键词搞懂 MyBatis
MyBatis 虽然功能强大,但核心就三个东西:
1. Mapper 接口(你的“菜单”)
这是一个 Java 接口,定义了你能对数据库做什么操作,比如:
public interface UserMapper {
User selectUserById(int id);
void insertUser(User user);
}
2. XML 映射文件(你的“菜谱”)
每个 Mapper 接口对应一个 .xml 文件,里面写具体的 SQL:
<!-- UserMapper.xml -->
<select id="selectUserById" resultType="User">
SELECT * FROM users WHERE id = #{id}
</select>
3. SqlSession(你的“服务员”)
程序通过它来执行 Mapper 中的方法:
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
✅ 我当初学的时候最大的误区:以为 MyBatis 会自动生成 SQL。其实它只是帮你执行你写的 SQL 并做对象映射,SQL 还是要自己写的!
四、实战项目:做一个用户管理系统
我们来做一个最简单的功能:根据 ID 查询用户信息。
步骤 1:建表
在 MySQL 中执行:
CREATE DATABASE mybatis_demo;
USE mybatis_demo;
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
email VARCHAR(100)
);
INSERT INTO users (name, email) VALUES
('张三', 'zhangsan@example.com'),
('李四', 'lisi@example.com');
步骤 2:创建 Java 实体类
// src/main/java/com/example/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; }
}
步骤 3:编写 Mapper 接口
// src/main/java/com/example/UserMapper.java
public interface UserMapper {
User selectUserById(int id);
}
步骤 4:编写 XML 映射文件
在 src/main/resources 下创建 com/example/UserMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.UserMapper">
<select id="selectUserById" resultType="com.example.User">
SELECT id, name, email FROM users WHERE id = #{id}
</select>
</mapper>
🔑 关键点:
namespace必须和接口全路径一致;resultType是返回对象的完整类名。
步骤 5:配置 MyBatis(mybatis-config.xml)
在 src/main/resources 下创建:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo?useSSL=false&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="your_password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/example/UserMapper.xml"/>
</mappers>
</configuration>
步骤 6:写主程序测试
// src/main/java/com/example/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;
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 user = mapper.selectUserById(1);
System.out.println("用户ID: " + user.getId());
System.out.println("姓名: " + user.getName());
System.out.println("邮箱: " + user.getEmail());
}
}
}
运行后,你应该看到:
用户ID: 1
姓名: 张三
邮箱: zhangsan@example.com
🎉 恭喜!你已经完成了第一个 MyBatis 程序!
五、新手常见问题 & 解决方案
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
ClassNotFoundException: com.mysql.cj.jdbc.Driver |
MySQL 驱动没加或版本不对 | 检查 pom.xml 是否包含 8.0+ 驱动 |
Mapped Statements collection does not contain value |
XML 的 namespace 或 id 写错 | 确保 namespace=接口全路径,id=方法名 |
| 查询结果为 null | 字段名和 Java 属性名不一致(如数据库是 user_name,Java 是 userName) | 使用 <resultMap> 或开启驼峰命名自动转换 |
| 找不到 UserMapper.xml | 路径不对或未在 config 中注册 | XML 放在 resources 下对应包路径,并在 <mappers> 中声明 |
💬 实战经验分享:我在做产品时,经常遇到字段名不一致的问题。后来统一规定:数据库用下划线(user_name),Java 用驼峰(userName),并在
mybatis-config.xml中加一行:<settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
六、下一步学习建议
你现在已经掌握了 MyBatis 的基础!接下来可以:
- 学 CRUD 全套操作:尝试实现插入、更新、删除
- 了解动态 SQL:比如
if、foreach标签,让 SQL 更灵活 - 整合 Spring Boot:实际产品中,MyBatis 几乎都和 Spring 一起用
- 对比其他框架:比如 Hibernate(全自动 ORM) vs MyBatis(半自动)
🌟 最后的话:技术没有“最好”,只有“最合适”。MyBatis 的优势在于SQL 可控性强,特别适合需要精细优化查询的产品场景。而如果你来自 Python 背景,会发现 Java 生态更强调“明确配置”而非“约定优于配置”,这正是 MyBatis 需要写 XML 的原因。
希望这篇教程能帮你少走弯路。记住:所有复杂的框架,拆开看都是简单的零件组合。动手写一遍,比看十遍文档都管用!
Happy Coding!

评论 0