MyBatis基础教程:Java持久层框架入门
作者:一位维护过多个开源项目的后端工程师
写作初衷:我当初学MyBatis时,被各种配置和概念绕得晕头转向。如今看到很多初学者在简历上写“熟悉MyBatis”,却连基本的SQL映射都搞不清楚,实在可惜。这篇教程就是为零基础朋友量身打造——哪怕你只写过Python脚本,也能看懂!
为什么选择MyBatis?——技术选型对比
在开始动手前,我们先搞清楚一个问题:什么是MyBatis?它和其他数据库访问方式有什么区别?
简单来说,MyBatis是一个Java持久层框架。所谓“持久层”,就是负责把程序中的数据(比如一个User对象)存到数据库里,或者从数据库读出来。
如果你用过Python,可能接触过sqlite3、pymysql或ORM框架如SQLAlchemy。Java生态也有类似工具,常见的有三种:
| 技术方案 | 特点 | 适合场景 |
|---|---|---|
| 原生JDBC | 直接调用数据库驱动,代码繁琐,需要手动处理连接、异常、资源关闭等 | 学习原理、极简项目 |
| Hibernate / JPA | 全自动ORM(对象关系映射),写Java类就能自动生成SQL,但学习曲线陡峭 | 快速开发、复杂业务模型 |
| MyBatis | 半自动ORM,SQL写在XML或注解中,开发者对SQL有完全控制权 | 需要灵活SQL、性能敏感场景 |
我当初学的时候,公司用的就是MyBatis。因为它既避免了JDBC的重复样板代码,又不像Hibernate那样“黑盒”——你可以清晰地看到每一条SQL,调试起来心里有底。
📌 小贴士:很多大厂(如阿里、美团)在核心系统中选择MyBatis,正是因为其可控性和性能可优化性。你的简历上如果能写出“MyBatis + 自定义SQL优化”,会比单纯写“使用Spring Data JPA”更有说服力。
环境准备:5分钟搭好开发环境
我们不需要复杂的IDE,但为了效率,建议使用 IntelliJ IDEA(社区版免费) 或 VS Code + Java插件。
第一步:安装必要软件
- JDK 8+(推荐JDK 11)
- 验证:终端输入
java -version
- 验证:终端输入
- Maven(项目构建工具)
- 验证:终端输入
mvn -v
- 验证:终端输入
- MySQL 5.7+(或其他数据库,本文以MySQL为例)
- 创建一个测试数据库:
CREATE DATABASE mybatis_demo;
- 创建一个测试数据库:
💡 如果你习惯用Python,可以把Maven理解为
pip,它用来管理Java项目的依赖包。
第二步:创建Maven项目
打开终端,执行以下命令创建一个空项目:
mvn archetype:generate \
-DgroupId=com.example \
-DartifactId=mybatis-tutorial \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false
进入项目目录:
cd mybatis-tutorial
第三步:添加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</pmversion>
</dependency>
<!-- 单元测试(可选) -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
保存后,IDEA会自动下载依赖(相当于Python的pip install)。
核心概念:用最简单的语言讲清楚
MyBatis的核心思想就一句话:把SQL和Java代码解耦。
具体来说,它通过以下组件工作:
1. SqlSessionFactory:工厂类
- 负责创建数据库会话(
SqlSession) - 只需初始化一次,通常做成单例
2. SqlSession:数据库会话
- 类似Python中的
cursor,用来执行SQL - 每次操作数据库都要用它
3. Mapper接口 + XML映射文件
- 接口:定义方法,如
User selectUserById(int id); - XML文件:写具体的SQL语句,并告诉MyBatis如何把结果转成Java对象
我当初最大的困惑是:“为什么要有XML?”
答案是:让SQL集中管理,方便DBA审核和优化。你甚至可以把SQL交给专门的SQL工程师写,Java程序员只管调用接口。
实战项目:做一个用户查询功能
我们将实现一个最简单的功能:根据ID查询用户信息。
步骤1:创建数据库表
USE mybatis_demo;
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');
步骤2:编写Java实体类
在 src/main/java/com/example 目录下创建 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 + "'}";
}
}
⚠️ 注意:字段名必须和数据库列名一致(或通过配置映射),否则查出来是null。
步骤3:配置MyBatis
在 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>
<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 XML文件 -->
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
步骤4:创建Mapper接口和XML
接口:src/main/java/com/example/UserMapper.java
package com.example;
public interface UserMapper {
User selectUserById(int id);
}
XML映射文件:src/main/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">
<select id="selectUserById" resultType="com.example.User" parameterType="int">
SELECT id, name, email FROM user WHERE id = #{id}
</select>
</mapper>
关键点解释:
namespace必须是接口的全限定名id必须和接口方法名一致resultType是返回对象的类型#{id}是参数占位符(防SQL注入!)
步骤5:编写测试代码
在 src/test/java/com/example/AppTest.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;
public class AppTest {
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接口(MyBatis会自动生成实现类!)
UserMapper mapper = session.getMapper(UserMapper.class);
// 5. 调用方法
User user = mapper.selectUserById(1);
System.out.println(user);
}
}
}
运行结果应为:
User{id=1, name='张三', email='zhangsan@example.com'}
✅ 成功!你已经完成了第一个MyBatis程序。
常见问题解答(新手避坑指南)
Q1:为什么查出来对象字段全是null?
- 原因:Java属性名和数据库列名不一致(比如Java用
userName,数据库是user_name) - 解决:
- 方案1:改Java属性名为
user_name(不推荐) - 方案2:在XML中使用
resultMap显式映射 - 方案3:开启MyBatis的驼峰命名转换(在config.xml中加
<setting name="mapUnderscoreToCamelCase" value="true"/>)
- 方案1:改Java属性名为
Q2:SQL写错了怎么办?怎么调试?
- MyBatis默认不打印SQL。要开启日志,可在
mybatis-config.xml中加:
这样就能看到实际执行的SQL了。<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
Q3:能不能不用XML,直接在Java代码里写SQL?
可以!MyBatis支持注解方式:
public interface UserMapper {
@Select("SELECT id, name, email FROM user WHERE id = #{id}")
User selectUserById(int id);
}
但复杂SQL(如多表关联)还是推荐用XML,更清晰、易维护。
Q4:我之前用Python写数据库,感觉比Java简单多了?
确实,Python的pymysql几行代码就能查数据。但Java的优势在于工程化和类型安全。MyBatis虽然配置多一点,但换来的是:
- 编译期检查(拼错字段名会报错)
- IDE自动补全
- 大型项目可维护性
💬 我的建议:不要因为初期配置繁琐就放弃。一旦搭好框架,后续开发效率远超手写JDBC。
学习建议:下一步怎么走?
你已经掌握了MyBatis的基础。接下来可以:
深入学习:
- 学习
resultMap处理复杂映射 - 掌握动态SQL(
<if>,<foreach>等标签) - 了解缓存机制(一级缓存、二级缓存)
- 学习
结合Spring Boot:
- 实际项目中MyBatis几乎都和Spring一起用
- 学习
mybatis-spring-boot-starter自动配置
性能优化:
- 学会使用
PageHelper分页 - 理解N+1查询问题及解决方案
- 学会使用
写进简历:
- 不要只写“使用MyBatis”
- 改成:“基于MyBatis实现用户模块,通过自定义SQL优化查询性能,响应时间降低40%”
最后提醒:技术深度比广度更重要。与其在简历上罗列10个框架,不如把MyBatis的原理和最佳实践吃透。毕竟,面试官问一句“#{}和${}的区别”,就能看出你是不是真的用过。
结语
MyBatis不是最难的框架,但它代表了一种务实的开发哲学:不隐藏SQL,把控制权交给开发者。无论你是刚从Python转Java,还是正在准备求职,掌握MyBatis都是后端开发的重要一步。
希望这篇教程能帮你少走弯路。如果觉得有用,欢迎点赞、收藏,也欢迎在开源社区提交PR改进文档——这正是我作为开源维护者最乐于看到的!

评论 0