MyBatis 是什么?为什么 Java 后端开发离不开它?
大家好,我是小林,一名 211 高校的计算机研究生,平时喜欢写技术博客帮助刚入门的学弟学妹们。今天我想和大家聊聊 MyBatis——这个在 Java 企业级开发中几乎“人手一份”的持久层框架。
我当初学 Java Web 的时候,一上来就面对 JDBC 冗长的样板代码:连接数据库、创建 Statement、处理 ResultSet、关闭资源……写得头大不说,还特别容易出错。后来接触了 MyBatis,才真正体会到“原来操作数据库可以这么清爽!”。
这篇文章就是为完全零基础的同学准备的。即使你连“持久层”是什么都不知道,也没关系!我会用最直白的语言、最简单的例子,带你一步步搭建第一个 MyBatis 项目,并解释清楚核心概念。对了,虽然标题提到了 Go,但本文重点是 Java ——不过文末我会简单对比下 Go 中常用的数据库操作方式,帮助有跨语言兴趣的同学建立认知桥梁。
一、环境准备:5 分钟搭好开发环境
要跑 MyBatis,你需要以下工具:
| 工具 | 版本建议 | 说明 |
|---|---|---|
| JDK | 8 或 11 | Java 开发必备 |
| Maven | 3.6+ | 依赖管理工具(也可用 Gradle,但本文用 Maven) |
| IDE | IntelliJ IDEA 或 Eclipse | 推荐 IDEA,对 MyBatis 支持更好 |
| 数据库 | MySQL 5.7+ 或 8.0 | 本文以 MySQL 为例 |
步骤 1:创建 Maven 项目
打开 IDEA,新建一个 Maven 项目,不勾选任何模板(即不选 archetype)。项目结构如下:
mybatis-demo/
├── src/
│ ├── main/
│ │ ├── java/
│ │ └── resources/
│ └── test/
└── pom.xml
步骤 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>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
💡 小提示:如果你用的是 MySQL 8.0,记得驱动类名是
com.mysql.cj.jdbc.Driver,不是老版本的com.mysql.jdbc.Driver!
步骤 3:配置数据库
假设你本地已安装 MySQL,创建一个数据库和表:
CREATE DATABASE mybatis_demo;
USE mybatis_demo;
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
email VARCHAR(100)
);
二、核心概念:MyBatis 到底做了什么?
MyBatis 是一个 Java 持久层框架。所谓“持久层”,就是负责把程序中的对象(比如 User)存到数据库,或从数据库读出来变成对象。
它的核心思想很简单:
你写 SQL,它帮你执行并映射结果。
和 Hibernate 这类“全自动 ORM”不同,MyBatis 是“半自动”的——它不替你生成 SQL,而是让你掌控 SQL,同时省去手动设置参数、解析结果集的麻烦。
关键组件有三个:
- SqlSessionFactory:工厂,用来创建 SqlSession(整个应用通常只有一个)
- SqlSession:会话,代表一次数据库对话,可执行增删改查
- Mapper 接口 + XML 映射文件:定义 SQL 和 Java 方法的对应关系
三、实战:手把手写第一个 MyBatis 程序
我们来实现一个“插入用户并查询”的功能。
第 1 步:创建 User 实体类
// src/main/java/com/example/User.java
package com.example;
public class User {
private Integer id;
private String name;
private String email;
// 构造函数、getter/setter 省略(实际请补全)
public User(String name, String email) {
this.name = name;
this.email = email;
}
@Override
public String toString() {
return "User{id=" + id + ", name='" + name + "', email='" + email + "'}";
}
}
第 2 步:编写 MyBatis 配置文件
在 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="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>
<!-- 注册 Mapper 文件 -->
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
第 3 步:编写 Mapper 映射文件
在 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="com.example.UserMapper">
<insert id="insertUser" parameterType="com.example.User">
INSERT INTO user (name, email) VALUES (#{name}, #{email})
</insert>
<select id="selectAll" resultType="com.example.User">
SELECT * FROM user
</select>
</mapper>
注意:
namespace必须和后续的接口包名一致(虽然这里我们没写接口,但规范如此)。
第 4 步:编写测试代码
// src/test/java/com/example/MyBatisTest.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 org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class MyBatisTest {
@Test
public void testInsertAndSelect() 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. 执行插入
session.insert("com.example.UserMapper.insertUser", new User("张三", "zhangsan@example.com"));
// 5. 提交事务(重要!默认不自动提交)
session.commit();
// 6. 查询所有
List<User> users = session.selectList("com.example.UserMapper.selectAll");
for (User user : users) {
System.out.println(user);
}
}
}
}
运行这个测试,你应该看到控制台输出刚插入的用户信息!
四、新手常见问题 & 避坑指南
❓ 为什么数据没插入成功?
- 原因:MyBatis 默认不自动提交事务!
- 解决:务必调用
session.commit(),或者在openSession(true)中传入true开启自动提交(仅用于测试)。
❓ 报错 “Cannot resolve class ‘com.mysql.cj.jdbc.Driver’”?
- 原因:MySQL 8 驱动类名变了。
- 解决:确认
pom.xml中引入的是 8.x 版本驱动,并在配置中使用com.mysql.cj.jdbc.Driver。
❓ XML 文件修改后不生效?
- 原因:IDEA 默认不把 resources 下的 XML 编译到 target。
- 解决:在
pom.xml的<build>中添加资源过滤(网上搜“IDEA mybatis xml not found”即可)。
❓ 能不用 XML 吗?
当然可以!MyBatis 也支持注解方式(如 @Select),但复杂 SQL 建议用 XML,更清晰、易维护。
五、对比一下:Java 用 MyBatis,Go 用什么?
虽然本文聚焦 Java,但很多同学也学 Go。简单对比下:
| 语言 | 常用数据库方案 | 特点 |
|---|---|---|
| Java | MyBatis / JPA / Spring Data JPA | MyBatis 灵活可控,适合复杂查询 |
| Go | GORM / sqlx / Ent | GORM 类似 Hibernate,sqlx 更接近 MyBatis 风格 |
比如在 Go 中用 sqlx(类似 MyBatis 的轻量库):
var users []User
db.Select(&users, "SELECT * FROM user WHERE name = ?", name)
可以看到,核心思想是一致的:SQL 由你写,框架帮你映射。只是语言生态不同,工具链有差异。
六、下一步怎么学?
- 掌握 Mapper 接口方式:用接口替代字符串调用(如
userMapper.insertUser(user)),更安全。 - 学习动态 SQL:
<if>,<foreach>等标签处理复杂条件。 - 整合 Spring Boot:实际项目中 MyBatis 几乎都和 Spring 一起用。
- 理解一级/二级缓存:提升性能的关键机制。
我当初就是从这样一个“插入用户”的小 demo 开始,慢慢搞懂了整个 ORM 体系。别怕慢,每个高手都是从
Hello World走过来的。
希望这篇教程能帮你迈出 MyBatis 的第一步!如果觉得有用,欢迎关注我的博客,后面我会更新《MyBatis + Spring Boot 整合实战》系列。
记住:写代码不怕错,怕的是不敢运行。现在,就去敲一遍吧!

评论 0