MyBatis基础教程:Java持久层框架入门
大家好,我是一名从培训班出来的前端转后端开发者。虽然现在主要写 Java 后端,但我还记得当初刚接触数据库操作时那种“一脸懵”的感觉——JDBC 写起来又啰嗦又容易出错,SQL 和 Java 代码混在一起简直像意大利面!后来接触到 MyBatis,才真正体会到什么叫“开发效率起飞”。
今天这篇教程,就是专门写给和我当初一样 完全零基础 的新手朋友的。我会用最直白的语言、最清晰的步骤,带你从零搭建一个能跑起来的 MyBatis 项目。哪怕你连“持久层”是啥都不知道,也没关系!
为什么我要写这篇?
因为我在 GitHub 上看到太多新手被 MyBatis 的配置搞到崩溃,而很多教程一上来就讲“动态 SQL”“缓存机制”,根本不管新人能不能跑通第一行代码。所以,我决定写一篇 只关注“跑起来” 的实战入门文。
一、MyBatis 是什么?用来干啥的?
简单说:MyBatis 是一个帮你把 Java 对象和数据库记录互相转换的工具。
- 你想把用户信息存进数据库?MyBatis 帮你生成 INSERT 语句。
- 你想从数据库查出商品列表?MyBatis 自动把结果变成 Java 对象列表。
它属于 持久层框架(Persistence Framework)——所谓“持久层”,就是负责把内存中的数据“持久化”到硬盘(比如数据库)的那一层代码。
为什么不用原生 JDBC?
对比一下:
| 方式 | 优点 | 缺点 |
|---|---|---|
| 原生 JDBC | 控制精细 | 代码冗长、重复、易出错 |
| MyBatis | 简洁、灵活、易维护 | 需要学习配置和映射规则 |
我当初写 JDBC,光是 Connection、PreparedStatement、ResultSet 的关闭和异常处理就能写半页代码。而 MyBatis 几乎全自动处理这些!
二、环境准备:5 分钟搭好开发环境
我们不需要复杂工具,只需要以下三样:
- JDK 8+(推荐 JDK 11)
- Maven(项目依赖管理)
- 一个数据库(这里用 MySQL)
💡 提示:如果你还没装这些,可以去官网下载,或者用 SDKMAN!(Linux/macOS)快速安装。Windows 用户直接下安装包就行。
步骤 1:创建 Maven 项目
打开终端,执行:
mvn archetype:generate -DgroupId=com.example -DartifactId=mybatis-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
这会生成一个基础 Maven 项目。
步骤 2:添加 MyBatis 和 MySQL 依赖
编辑 pom.xml,在 <dependencies> 里加入:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
✅ 小贴士:版本号可能会更新,你可以去 MyBatis 官方 GitHub 查最新版。
步骤 3:准备数据库
假设你本地有 MySQL,执行以下 SQL 创建测试库和表:
CREATE DATABASE mybatis_demo;
USE mybatis_demo;
CREATE TABLE user (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100)
);
INSERT INTO user (name, email) VALUES
('张三', 'zhangsan@example.com'),
('李四', 'lisi@example.com');
三、核心概念:3 个关键文件讲清楚
MyBatis 的工作靠三个东西配合:
- MyBatis 配置文件(
mybatis-config.xml)→ 告诉 MyBatis 数据库在哪、怎么连 - Mapper 接口(Java 接口)→ 定义你要执行哪些数据库操作
- Mapper XML 文件 → 写具体的 SQL 语句,并告诉 MyBatis 如何把结果映射成 Java 对象
我当初最困惑的就是“为什么要有 XML?”——其实你可以用注解代替,但 XML 更灵活,尤其适合复杂查询。所以我们先学 XML 方式。
目录结构建议
在 src/main/resources 下创建:
resources/
├── mybatis-config.xml
└── mapper/
└── UserMapper.xml
在 src/main/java/com/example 下创建:
User.java // 实体类
UserMapper.java // Mapper 接口
Main.java // 测试入口
四、实战:手把手写一个查询功能
第 1 步:写实体类 User.java
package com.example;
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 + "'}";
}
}
第 2 步:写 Mapper 接口 UserMapper.java
package com.example;
import java.util.List;
public interface UserMapper {
List<User> findAll(); // 查询所有用户
}
第 3 步:写 Mapper XML mapper/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="findAll" resultType="com.example.User">
SELECT id, name, email FROM user
</select>
</mapper>
🔑 关键点:
namespace必须是接口的全限定名id必须和接口方法名一致resultType指定返回对象的类型
第 4 步:写主配置文件 mybatis-config.xml
<?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="你的密码"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
第 5 步:写测试代码 Main.java
package com.example;
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. 打开 Session
try (SqlSession session = sqlSessionFactory.openSession()) {
// 4. 获取 Mapper 接口
UserMapper mapper = session.getMapper(UserMapper.class);
// 5. 调用方法
List<User> users = mapper.findAll();
users.forEach(System.out::println);
}
}
}
运行!
在项目根目录执行:
mvn compile exec:java -Dexec.mainClass="com.example.Main"
如果看到输出:
User{id=1, name='张三', email='zhangsan@example.com'}
User{id=2, name='李四', email='lisi@example.com'}
恭喜!你已经成功跑通了第一个 MyBatis 程序!
五、新手常见问题 & 避坑指南
❌ 问题 1:ClassNotFoundException: com.mysql.cj.jdbc.Driver
原因:MySQL 驱动没加或版本不对。
解决:确认 pom.xml 里有 mysql-connector-java 依赖,且版本 ≥ 8.0。
❌ 问题 2:Mapped Statements collection does not contain value for ...
原因:XML 的 namespace 或 id 和接口不匹配。
检查:
namespace="com.example.UserMapper"- 方法名
findAll和 XML 中id="findAll"一致
❌ 问题 3:字段查出来是 null
原因:数据库列名和 Java 属性名不一致(比如数据库是 user_name,Java 是 userName)。
解决:在 XML 中用 resultMap 显式映射,或者开启驼峰转换:
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
⚠️ 避坑提醒
- 不要手动 close Session:用
try-with-resources自动关闭(如上面的try (SqlSession ...)) - Mapper 接口不能有实现类:MyBatis 会自动生成代理实现
- SQL 写在 XML 里,不是 Java 里:这是 MyBatis 的核心思想——解耦
六、下一步学习建议
你现在已经掌握了 MyBatis 最基础的查询功能。接下来可以:
- 尝试增删改:在
UserMapper中添加insert、update、delete方法,并在 XML 中写对应 SQL - 学习参数传递:比如
User findById(int id),如何传参? - 了解 #{} 和 ${} 的区别:防止 SQL 注入的关键!
- 探索 MyBatis-Plus:国内流行的增强版,简化 CRUD
🌟 最后送你一句话:所有复杂的框架,都是从“跑通第一行代码”开始的。别怕配置麻烦,先让它跑起来,再慢慢理解原理。
如果你觉得这篇教程帮到了你,欢迎去 GitHub 给我点个 star(虽然这不是我的项目 😄)。也欢迎留言告诉我你还想学什么——毕竟,我也是从培训班出来的,深知新手需要什么。
Happy Coding!

评论 0