MyBatis到底难不难?零基础也能上手的Java持久层入门实战
大家好,我是老张,一名985毕业、在一线大厂干了多年后端开发的工程师。平时除了写代码,我也喜欢在掘金分享一些技术教程。最近收到不少私信:“我刚学Java,数据库怎么连?”“听说MyBatis很火,但完全看不懂。”
其实我当初学的时候也是一头雾水——为什么不能直接用JDBC?XML配置文件是啥?结果集怎么自动变成Java对象?这些问题,今天我就用最直白的方式,带你从零搭建一个MyBatis项目,彻底搞懂它的核心逻辑。
友情提示:本文专为完全零基础的同学设计。即使你只写过“Hello World”,也能跟下来。文末还会解答新手最常踩的坑!
一、MyBatis 是什么?为什么后端开发离不开它?
简单说,MyBatis 是一个 Java 的“数据库翻译官”。
想象一下:你的 Java 程序想查用户信息,但数据库只认 SQL(比如 SELECT * FROM user WHERE id = 1)。而你希望拿到的是一个 User 对象,不是一堆字段。这时候,MyBatis 就在中间做两件事:
- 把 Java 方法调用 → 转成 SQL 语句
- 把数据库返回的结果 → 自动封装成 Java 对象
✅ 对比传统 JDBC:
以前你要手动拼 SQL、处理连接、遍历 ResultSet、关资源……代码又长又容易出错。
用了 MyBatis,这些脏活累活它全包了,你只关心“我要查什么”。
那 Python 呢?和 MyBatis 有关系吗?
很多同学会问:“我之前学 Python 用 SQLAlchemy,Java 里 MyBatis 是不是类似?”
答案是:思路相似,但实现不同。
| 框架 | 语言 | 特点 |
|---|---|---|
| SQLAlchemy | Python | ORM 更“全自动”,隐藏 SQL |
| MyBatis | Java | 半自动 ORM,SQL 可见 |
MyBatis 的最大优势就是:SQL 写在哪、怎么写,你说了算。这对性能调优、复杂查询非常友好。这也是为什么国内大厂(阿里、腾讯等)后端系统大量使用 MyBatis。
二、环境准备:5分钟搭好开发环境
我们用最轻量的方式搭建项目。不需要 Spring Boot,纯 MyBatis + Maven,避免初学者被框架干扰。
步骤 1:安装必备工具
- JDK 8+(推荐 JDK 11)
- Maven(用于管理依赖)
- 任意 IDE(IntelliJ IDEA / Eclipse)
步骤 2:创建 Maven 项目
mvn archetype:generate -DgroupId=com.example -DartifactId=mybatis-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
步骤 3:添加 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</version>
</dependency>
💡 避坑指南:
很多新手卡在驱动版本。MySQL 8.x 必须用 8.0+ 驱动,否则会报Public Key Retrieval is not allowed错误。
三、核心概念:3个文件讲清楚 MyBatis 工作流
MyBatis 的运行靠三个关键文件配合:
1. mybatis-config.xml → 全局配置(连哪个库?用什么设置?)
2. UserMapper.xml → SQL 映射文件(写具体 SQL)
3. UserMapper.java → 接口(定义方法,不用写实现!)
1. 全局配置:mybatis-config.xml
放在 src/main/resources 下:
<?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/testdb?useSSL=false&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="your_password"/>
</dataSource>
</environment>
</environments>
<!-- 告诉 MyBatis 去哪找 SQL 映射文件 -->
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
🔍 重点参数说明:
url中的&是 XML 转义,实际是&testdb是你的数据库名,先手动建好
2. 定义实体类:User.java
package com.example.model;
public class User {
private int id;
private String name;
private String email;
// 必须有无参构造器(MyBatis 用反射创建对象)
public User() {}
// getter / setter 省略(IDE 可自动生成)
}
3. 编写 Mapper 接口和 XML
UserMapper.java(接口):
package com.example.mapper;
import com.example.model.User;
import java.util.List;
public interface UserMapper {
User selectUserById(int id);
List<User> selectAllUsers();
}
UserMapper.xml(SQL 映射):
<?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="selectUserById" resultType="com.example.model.User">
SELECT id, name, email FROM user WHERE id = #{id}
</select>
<select id="selectAllUsers" resultType="com.example.model.User">
SELECT id, name, email FROM user
</select>
</mapper>
📌 关键规则:
namespace必须等于接口的全限定名id必须等于接口中的方法名#{id}是安全的占位符,防 SQL 注入
四、实战:动手写一个查询用户的小程序
现在,我们把前面的零件组装起来!
步骤 1:准备数据库
CREATE DATABASE testdb;
USE testdb;
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:编写主程序
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.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. 获取 SqlSession(代表一次数据库会话)
try (SqlSession session = sqlSessionFactory.openSession()) {
// 4. 获取 Mapper 接口的代理对象
UserMapper mapper = session.getMapper(UserMapper.class);
// 5. 调用方法
User user = mapper.selectUserById(1);
System.out.println("查到用户: " + user.getName());
List<User> users = mapper.selectAllUsers();
System.out.println("共查到 " + users.size() + " 个用户");
}
}
}
运行结果:
查到用户: 张三
共查到 2 个用户
✅ 恭喜!你已经跑通了第一个 MyBatis 程序!
五、新手常见问题 & 实战经验总结
根据我带实习生的经验,90% 的问题集中在以下几点:
❌ 问题1:Mapper method was not found
原因:XML 的 namespace 或 id 和接口方法对不上。
解决:严格检查包名、类名、方法名是否完全一致。
❌ 问题2:Property 'xxx' not found
原因:数据库字段名(如 user_name)和 Java 属性名(userName)不一致。
解决:用 <resultMap> 显式映射:
<resultMap id="UserMap" type="User">
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
</resultMap>
<select id="selectUser" resultMap="UserMap">...</select>
❌ 问题3:中文乱码
解决:在 JDBC URL 加 characterEncoding=utf8:
jdbc:mysql://...&characterEncoding=utf8
💡 我的实战建议:
- SQL 写在 XML 里,别用注解:后期维护更方便
- 所有 Mapper 方法加
@Param注解(如果参数不止一个):User findUser(@Param("name") String name, @Param("age") int age); - 不要手动管理事务:初期用
session.commit(),后期结合 Spring
六、下一步学什么?
你现在掌握了 MyBatis 的核心流程。接下来建议:
进阶学习:
- 动态 SQL(
<if>,<foreach>) - 关联查询(一对一、一对多)
- 缓存机制(一级/二级缓存)
- 动态 SQL(
整合 Spring Boot:
真实项目几乎都用 Spring Boot + MyBatis。可以学mybatis-spring-boot-starter。对比其他框架:
了解 Hibernate(全自动 ORM)、JPA,理解不同场景的选择逻辑。
最后送大家一句话:“框架只是工具,理解数据流动的本质才是核心。”
我当初也是从一行一行 debug 开始的。坚持动手,你一定能行!
延伸阅读:
- MyBatis 官方文档(中文)
- 《MyBatis 从入门到精通》—— 刘增辉(适合系统学习)
如果你觉得这篇教程帮到了你,欢迎点赞收藏!也欢迎在评论区留言你的问题,我会一一解答。

评论 0