MyBatis基础教程:Java持久层框架入门

程序员阿远
2025-12-15 11:13
阅读 360

作者:一位维护过多个开源项目的后端工程师
写作初衷:我当初学MyBatis时,被各种配置和概念绕得晕头转向。如今看到很多初学者在简历上写“熟悉MyBatis”,却连基本的SQL映射都搞不清楚,实在可惜。这篇教程就是为零基础朋友量身打造——哪怕你只写过Python脚本,也能看懂!


为什么选择MyBatis?——技术选型对比

在开始动手前,我们先搞清楚一个问题:什么是MyBatis?它和其他数据库访问方式有什么区别?

简单来说,MyBatis是一个Java持久层框架。所谓“持久层”,就是负责把程序中的数据(比如一个User对象)存到数据库里,或者从数据库读出来。

如果你用过Python,可能接触过sqlite3pymysql或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插件

第一步:安装必要软件

  1. JDK 8+(推荐JDK 11)
    • 验证:终端输入 java -version
  2. Maven(项目构建工具)
    • 验证:终端输入 mvn -v
  3. 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&amp;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"/>

Q2:SQL写错了怎么办?怎么调试?

  • MyBatis默认不打印SQL。要开启日志,可在mybatis-config.xml中加:
    <settings>
      <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    
    这样就能看到实际执行的SQL了。

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的基础。接下来可以:

  1. 深入学习

    • 学习 resultMap 处理复杂映射
    • 掌握动态SQL(<if>, <foreach> 等标签)
    • 了解缓存机制(一级缓存、二级缓存)
  2. 结合Spring Boot

    • 实际项目中MyBatis几乎都和Spring一起用
    • 学习 mybatis-spring-boot-starter 自动配置
  3. 性能优化

    • 学会使用 PageHelper 分页
    • 理解N+1查询问题及解决方案
  4. 写进简历

    • 不要只写“使用MyBatis”
    • 改成:“基于MyBatis实现用户模块,通过自定义SQL优化查询性能,响应时间降低40%”

最后提醒:技术深度比广度更重要。与其在简历上罗列10个框架,不如把MyBatis的原理和最佳实践吃透。毕竟,面试官问一句“#{}和${}的区别”,就能看出你是不是真的用过。


结语

MyBatis不是最难的框架,但它代表了一种务实的开发哲学:不隐藏SQL,把控制权交给开发者。无论你是刚从Python转Java,还是正在准备求职,掌握MyBatis都是后端开发的重要一步。

希望这篇教程能帮你少走弯路。如果觉得有用,欢迎点赞、收藏,也欢迎在开源社区提交PR改进文档——这正是我作为开源维护者最乐于看到的!

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝