MyBatis基础教程:Java持久层框架入门
大家好,我是一名工作5年的后端开发工程师。今天想和大家分享一个我在职业生涯早期就频繁使用的工具——MyBatis。我当初学的时候,面对一堆 XML 配置、SQL 映射、接口绑定这些概念,一度非常困惑。但后来发现,只要把核心思想理清楚,其实并不难。
这篇教程就是专门写给完全零基础的 Java 初学者的。我会用最直白的语言,带你一步步理解 MyBatis 是什么、怎么用,并手把手完成一个简单的项目。无论你是刚学完 Java 基础,还是第一次接触数据库操作,都能跟着做下来。
一、MyBatis 是什么?为什么要用它?
简单来说,MyBatis 是一个 Java 持久层框架。
那“持久层”又是什么?
你可以把它理解成“Java 程序和数据库之间的翻译官”。
比如你想从数据库里查一条用户信息,在没有框架的情况下,你得:
- 加载数据库驱动
- 建立连接
- 写 SQL 语句
- 执行查询
- 把结果集(ResultSet)一行行读出来
- 手动封装成 Java 对象
- 关闭连接、处理异常……
光是这些步骤,写一次就累死了,更别说重复几十次。
而 MyBatis 帮你自动做了大部分脏活累活,你只需要:
- 定义一个 Java 接口(比如
UserMapper) - 写一条 SQL(放在 XML 或注解里)
- 调用接口方法,直接拿到 Java 对象!
✅ 一句话总结:MyBatis 让你用面向对象的方式操作数据库,不用再和底层 JDBC 打交道。
二、环境准备:搭建开发环境
要运行 MyBatis,你需要以下资源:
| 资源 | 版本建议 | 说明 |
|---|---|---|
| JDK | 8 或以上 | Java 开发基础 |
| Maven | 3.6+ | 项目依赖管理(也可用 Gradle,本文用 Maven) |
| IDE | IntelliJ IDEA / Eclipse | 推荐 IDEA,对 MyBatis 支持更好 |
| 数据库 | MySQL 5.7+ / H2(内存数据库) | 本文使用 H2,无需安装 |
💡 为什么用 H2?
因为它是内存数据库,启动快、无需配置,特别适合教学和测试。等你熟悉了,再换成 MySQL 很容易。
步骤 1:创建 Maven 项目
打开 IDEA,新建一个 Maven 项目(不选模板),groupId 设为 com.example,artifactId 设为 mybatis-demo。
步骤 2:添加依赖
在 pom.xml 中加入以下依赖:
<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>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
步骤 3:初始化数据库
我们在 src/main/resources 下创建一个 schema.sql 文件,内容如下:
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
email VARCHAR(100)
);
INSERT INTO user (name, email) VALUES
('张三', 'zhangsan@example.com'),
('李四', 'lisi@example.com');
📌 注意:H2 会在程序启动时自动加载这个脚本(后面会配置)。
三、核心概念:用大白话讲清楚
MyBatis 有三个核心组件,记住它们就掌握了 80%:
1. SqlSessionFactory
- 字面意思:“SQL 会话工厂”
- 它负责读取配置文件(比如数据库连接信息),然后创建 SqlSession
- 整个应用一般只创建一次(单例)
2. SqlSession
- 代表一次数据库会话
- 你可以通过它执行 SQL、提交事务、关闭连接
- 但它不是线程安全的! 每次操作都要新建、用完关闭
3. Mapper(映射器)
- 这是你最常打交道的部分
- 它是一个 Java 接口 + XML 文件(或注解)
- 接口定义方法(如
User selectById(int id)) - XML/注解里写对应的 SQL
- MyBatis 自动把 SQL 结果映射成 Java 对象
🔑 关键思想:接口编程 + SQL 分离
四、实战项目:实现用户查询功能
我们现在来做一个最简单的功能:根据 ID 查询用户信息。
步骤 1:创建 User 实体类
// src/main/java/com/example/model/User.java
package com.example.model;
public class User {
private int id;
private String name;
private String email;
// 必须有无参构造函数(MyBatis 需要用反射创建对象)
public User() {}
// getter 和 setter
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 接口
// src/main/java/com/example/mapper/UserMapper.java
package com.example.mapper;
import com.example.model.User;
public interface UserMapper {
User selectById(int id);
}
步骤 3:编写 Mapper XML 文件
在 src/main/resources 下创建目录 mappers,然后新建 UserMapper.xml:
<!-- src/main/resources/mappers/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.mapper.UserMapper">
<select id="selectById" resultType="com.example.model.User">
SELECT id, name, email FROM user WHERE id = #{id}
</select>
</mapper>
📌 注意:
namespace必须是接口的全限定名id必须和接口方法名一致#{id}是参数占位符,MyBatis 会自动替换
步骤 4:配置 MyBatis(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"
"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="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>
<!-- 注册 Mapper XML 文件 -->
<mappers>
<mapper resource="mappers/UserMapper.xml"/>
</mappers>
</configuration>
🔍 解释几个关键点:
INIT=RUNSCRIPT FROM 'classpath:schema.sql':启动时自动执行初始化脚本DB_CLOSE_DELAY=-1:防止内存数据库被关闭<mappers>:告诉 MyBatis 去哪里找 XML 映射文件
步骤 5:编写测试代码
// src/test/java/com/example/AppTest.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 org.junit.Test;
import java.io.InputStream;
public class AppTest {
@Test
public void testSelectUser() 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 接口(MyBatis 自动生成实现类)
UserMapper mapper = session.getMapper(UserMapper.class);
// 5. 调用方法
User user = mapper.selectById(1);
System.out.println(user); // 应该输出:User{id=1, name='张三', email='zhangsan@example.com'}
}
}
}
运行这个测试,如果看到输出,恭喜你!MyBatis 已经跑起来了!
五、常见问题 & 避坑指南
❓ 问题1:Invalid bound statement (not found) 错误
原因:MyBatis 找不到你的 Mapper 方法。
检查点:
- XML 的
namespace是否和接口全名一致? - XML 的
id是否和方法名一致? mybatis-config.xml中是否注册了 XML 文件?- XML 文件是否在
resources目录下(Maven 默认不拷贝 .java 同名的 .xml)?
✅ 避坑建议:把 XML 放在
resources下,不要和 Java 文件混在一起。
❓ 问题2:属性无法赋值,全是 null
原因:数据库字段名和 Java 属性名不一致(比如数据库是 user_name,Java 是 userName)。
解决方案:
- 方案1:SQL 中用别名
SELECT user_name AS userName ... - 方案2:在
mybatis-config.xml中开启驼峰命名自动映射:
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
❓ 问题3:每次都要写 try-with-resources 太麻烦
进阶方案:可以用 MyBatis-Spring 或 MyBatis-Plus,它们能自动管理 SqlSession 生命周期。但作为入门,先掌握原生用法更重要。
六、学习建议:下一步怎么走?
MyBatis 的世界远不止这些。当你掌握了基础,可以按以下路径深入:
学会写增删改
尝试实现insertUser,updateUser,deleteUser,注意insert后如何获取自增 ID。学习动态 SQL
MyBatis 的<if>,<foreach>,<choose>能让你写出灵活的 SQL。了解注解方式
不想写 XML?可以用@Select("SELECT ...")直接写在接口上。整合 Spring Boot
实际项目中,MyBatis 几乎都和 Spring 一起用。Spring Boot 提供了mybatis-spring-boot-starter,几行配置就能搞定。性能优化
学习一级缓存、二级缓存、延迟加载等高级特性。
💬 我的建议:不要一上来就追求“最佳实践”。先跑通一个例子,再慢慢扩展。我当初就是靠反复修改那个
selectById方法,才真正理解了 MyBatis 的映射机制。
结语
这篇《MyBatis 基础教程》从零开始,带你完成了环境搭建、核心概念理解、实战编码和问题排查。虽然只有 3600 多字,但涵盖了初学者最需要的综合知识。
记住:框架只是工具,理解数据如何从数据库变成 Java 对象,才是本质。
希望这篇文章能成为你 Java 后端之路的一块垫脚石。如果你觉得有用,不妨动手敲一遍代码——编程这事儿,光看不练,永远学不会。
祝你编码愉快!

评论 0