MyBatis 到底是个啥?零基础也能轻松上手的 Java 持久层入门指南
大家好,我是你们的老朋友,一名 985 毕业后一直深耕后端开发的全栈工程师。这些年我在掘金写了几十篇入门教程,每次看到新手留言说“终于看懂了”,我就觉得特别值得。
今天这篇《MyBatis 到底是个啥?零基础也能轻松上手的 Java 持久层入门指南》,就是专门为你——刚接触 Java 开发、对数据库操作一头雾水的新手准备的。我当初学的时候,光是搞懂“持久层”这三个字就花了好几天。别担心,我会用最直白的话、最简单的例子,带你一步步把 MyBatis 玩明白。
友情提示:你不需要会前端,也不需要精通数据库,只要会写最基础的 Java 类和方法,就能跟着做!
一、MyBatis 是什么?为什么我们需要它?
简单说:MyBatis 是一个帮你用 Java 代码操作数据库的工具。
想象一下:你的 Java 程序要往 MySQL 里存用户信息。传统做法是:
- 加载数据库驱动
- 建立连接(Connection)
- 写 SQL 字符串
- 执行查询/更新
- 遍历结果集(ResultSet)
- 关闭所有资源
代码又长又容易出错,还特别难维护。
而 MyBatis 做了两件大事:
- 自动处理数据库连接和资源释放
- 让你用 Java 对象直接映射数据库记录(ORM)
比如,你有一个 User 类,MyBatis 能自动把数据库里的 id, name, email 字段变成一个 User 对象,省去手动 resultSet.getString("name") 的麻烦。
📌 关键概念提前说:
- 持久层(Persistence Layer):负责把内存中的数据“持久化”到硬盘(如数据库)的那部分代码。
- ORM(对象关系映映射):Java 对象 ↔ 数据库表行 的自动转换。
二、环境准备:5 分钟搭好开发环境
我们只需要以下工具:
| 工具 | 作用 | 推荐版本 |
|---|---|---|
| JDK | 运行 Java 程序 | JDK 8 或 11 |
| Maven | 项目依赖管理 | 3.6+ |
| IDE | 写代码 | IntelliJ IDEA(社区版免费) |
| MySQL | 数据库 | 5.7 或 8.0 |
| Navicat / DBeaver | 数据库可视化工具(可选) | 最新版 |
步骤 1:创建 Maven 项目
打开 IDEA → New Project → 选择 Maven → 不勾选模板 → 点击 Next。
填写:
- GroupId:
com.example - ArtifactId:
mybatis-demo
点击 Finish。
步骤 2:添加依赖(pom.xml)
在 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>
<!-- 日志(方便调试) -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.7</version>
</dependency>
💡 避坑提醒:MySQL 8.0 需要指定时区,后面配置文件会讲。
步骤 3:创建数据库和表
打开你的 MySQL 客户端,执行:
CREATE DATABASE mybatis_demo CHARACTER SET utf8mb4;
USE mybatis_demo;
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE
);
插入两条测试数据:
INSERT INTO user (name, email) VALUES
('张三', 'zhangsan@example.com'),
('李四', 'lisi@example.com');
三、核心配置:让 MyBatis 连上数据库
MyBatis 需要两个核心文件:
- mybatis-config.xml:全局配置(数据库连接、别名等)
- Mapper XML 文件:写 SQL 的地方
1. 创建 mybatis-config.xml
在 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>
<!-- 设置别名,避免写全类名 -->
<typeAliases>
<typeAlias alias="User" type="com.example.model.User"/>
</typeAliases>
<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=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="你的密码"/>
</dataSource>
</environment>
</environments>
<!-- 注册 Mapper 文件 -->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
⚠️ 注意:
&在 XML 中要写成&,否则会报错!
2. 创建 User 实体类
在 src/main/java/com/example/model/ 下创建 User.java:
package com.example.model;
public class User {
private Integer id;
private String name;
private String email;
// 必须要有无参构造器(MyBatis 反射需要)
public User() {}
// getter 和 setter
public Integer getId() { return id; }
public void setId(Integer 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 + "'}";
}
}
3. 创建 Mapper 接口和 XML
先建接口(约定优于配置):
src/main/java/com/example/mapper/UserMapper.java
package com.example.mapper;
import com.example.model.User;
import java.util.List;
public interface UserMapper {
List<User> findAll();
User findById(Integer id);
void insert(User user);
void update(User user);
void delete(Integer id);
}
再建对应的 XML 文件:
src/main/resources/mapper/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="com.example.mapper.UserMapper">
<!-- 查询所有用户 -->
<select id="findAll" resultType="User">
SELECT * FROM user
</select>
<!-- 根据 ID 查询 -->
<select id="findById" parameterType="int" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>
<!-- 插入用户 -->
<insert id="insert" parameterType="User">
INSERT INTO user (name, email) VALUES (#{name}, #{email})
</insert>
<!-- 更新用户 -->
<update id="update" parameterType="User">
UPDATE user SET name = #{name}, email = #{email} WHERE id = #{id}
</update>
<!-- 删除用户 -->
<delete id="delete" parameterType="int">
DELETE FROM user WHERE id = #{id}
</delete>
</mapper>
🔑 重点理解:
namespace必须是接口的全限定名id必须和接口方法名一致#{}是安全的占位符(防 SQL 注入)
四、实战:写一个主程序测试 CRUD
在 src/main/java/com/example/App.java 中写:
package com.example;
import com.example.mapper.UserMapper;
import com.example.model.User;
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.IOException;
import java.io.InputStream;
import java.util.List;
public class App {
public static void main(String[] args) throws IOException {
// 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);
// 测试查询所有
System.out.println("=== 查询所有用户 ===");
List<User> users = mapper.findAll();
users.forEach(System.out::println);
// 测试插入
System.out.println("\n=== 插入新用户 ===");
User newUser = new User();
newUser.setName("王五");
newUser.setEmail("wangwu@example.com");
mapper.insert(newUser);
// 提交事务!否则不会生效
session.commit();
// 再次查询
System.out.println("\n=== 插入后再次查询 ===");
users = mapper.findAll();
users.forEach(System.out::println);
}
}
}
运行结果应该类似:
=== 查询所有用户 ===
User{id=1, name='张三', email='zhangsan@example.com'}
User{id=2, name='李四', email='lisi@example.com'}
=== 插入新用户 ===
=== 插入后再次查询 ===
User{id=1, name='张三', email='zhangsan@example.com'}
User{id=2, name='李四', email='lisi@example.com'}
User{id=3, name='王五', email='wangwu@example.com'}
✅ 重要提醒:
- 必须调用
session.commit()才会真正写入数据库!- 使用 try-with-resources 自动关闭 session,避免连接泄漏
五、新手常见问题 & 解决方案
❓ 问题 1:运行报错 ClassNotFoundException: com.mysql.cj.jdbc.Driver
原因:没加 MySQL 驱动依赖,或版本太旧。
解决:确认 pom.xml 中有 mysql-connector-java 且版本 ≥ 8.0。
❓ 问题 2:插入数据后查不到,但数据库里有?
原因:忘了 session.commit()。
解决:所有增删改操作后必须提交事务。
❓ 问题 3:中文乱码?
原因:数据库或连接没设 UTF-8。
解决:
- 建库时指定
CHARACTER SET utf8mb4 - JDBC URL 加上
?useUnicode=true&characterEncoding=utf8
❓ 问题 4:Invalid bound statement (not found) 错误
原因:Mapper 接口和 XML 不匹配。
检查清单:
- namespace 是否是接口全名?
- 方法名是否和 XML 中的 id 一致?
- XML 是否被正确注册到 mybatis-config.xml?
- resources 目录是否被标记为资源根目录?(IDEA 右键 → Mark Directory as → Resources Root)
六、学习建议:下一步该学什么?
恭喜你已经迈出了第一步!接下来可以:
深入 MyBatis
- 动态 SQL(
<if>,<foreach>) - 关联查询(一对一、一对多)
- 缓存机制
- 动态 SQL(
整合 Spring Boot
实际项目中 MyBatis 几乎都和 Spring Boot 一起用。学完基础后,立刻尝试mybatis-spring-boot-starter。对比其他框架
了解 JPA/Hibernate,知道什么时候用 MyBatis(灵活 SQL),什么时候用 JPA(快速原型)。写个小项目
比如“博客系统”、“待办清单”,把 CRUD 用起来。编程是练出来的,不是看出来的。
最后说两句
我当初学 MyBatis 时,光是配环境就折腾了一整天。后来发现,很多教程跳过了“为什么这么配”,导致新手一脸懵。所以这篇教程我特意拆解了每一步,连 & 这种细节都没放过。
记住:所有复杂的框架,底层逻辑都很简单。MyBatis 本质就是“用 XML 或注解写 SQL,用 Java 对象接结果”。
如果你能跑通上面的代码,你就已经超过 50% 的初学者了。坚持下去,下一个后端高手就是你!
👉 互动时间:你在学习 MyBatis 时遇到过什么奇葩问题?欢迎在评论区留言,我会一一解答!
作者:一位爱写教程的 985 全栈工程师
首发平台:掘金
版权声明:原创不易,转载请注明出处

评论 0