技术文章

Prompt修理师
2026-06-24 22:18
阅读 635

零基础掌握MyBatis持久层框架入门指南

大家好,我是一名开源项目维护者,平时也负责给团队的新人做后端培训。最近发现很多刚接触Java持久层的同学对MyBatis感到迷茫,所以我决定写下这篇教程。我当初学的时候,也是被各种XML配置和映射关系搞得晕头转向,踩了无数坑。今天,我会用最通俗的语言,带大家从零开始,深度解析MyBatis的核心原理与实战用法。

环境准备

要开始我们的实战,首先需要准备好开发环境。

  1. 数据库准备:安装MySQL,并创建一个名为mybatis_demo的数据库。执行以下建表语句:
CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`)
);
  1. 引入Maven依赖:在项目的pom.xml中引入MyBatis核心包和MySQL驱动。
<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.13</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
    </dependency>
</dependencies>

核心概念

在动手写代码前,我们必须搞懂MyBatis的三个核心概念。这里也是面试的高频考点,很多大厂的面试题都会围绕它们展开深度提问。

  • SqlSessionFactory:你可以把它理解为“数据库连接池的管理者”。它是线程安全的,整个应用生命周期中只需要创建一个实例,用来生产SqlSession。
  • SqlSession:它是执行SQL的“会话”。类似于JDBC中的Connection,但它封装了所有执行SQL的方法。注意,它是线程不安全的,每次请求都必须创建新的实例,用完即关。
  • Mapper:它是接口与XML文件的桥梁。我们只需要定义接口,MyBatis会通过动态代理自动生成代理对象,帮我们实现接口方法。

为了更直观地理解,我们可以用文字画一个简单的执行流程图: [应用代码] -> 获取[SqlSessionFactory] -> 开启[SqlSession] -> 获取[Mapper代理对象] -> 执行SQL -> 返回结果并关闭会话。

实战项目

接下来,我们一步步完成一个完整的数据库操作项目。

第一步:创建实体类

public class User {
    private Integer id;
    private String username;
    private Integer age;
    // 省略getter、setter和toString方法
}

第二步:编写Mapper接口

public interface UserMapper {
    User selectById(Integer id);
    int insertUser(User user);
}

第三步:编写Mapper XML配置resources目录下创建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="selectById" resultType="com.example.entity.User">
        SELECT * FROM user WHERE id = #{id}
    </select>
    <insert id="insertUser">
        INSERT INTO user(username, age) VALUES(#{username}, #{age})
    </insert>
</mapper>

第四步:编写MyBatis核心配置文件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-configuration.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"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>

第五步:测试运行 在测试类中,我们模拟批量插入数据的场景。在遍历集合时,如果遇到年龄为负数的异常数据,我们可以捕获异常并Continue处理下一条数据,保证整个批量任务不会因为单条脏数据而中断。

public class MyBatisTest {
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        
        try (SqlSession session = sqlSessionFactory.openSession()) {
            UserMapper mapper = session.getMapper(UserMapper.class);
            
            // 单条查询测试
            User user = mapper.selectById(1);
            System.out.println("查询结果: " + user.getUsername());
            
            // 批量处理逻辑演示
            List<User> userList = getUserList();
            for (User u : userList) {
                try {
                    if (u.getAge() < 0) throw new IllegalArgumentException("年龄异常");
                    mapper.insertUser(u);
                } catch (Exception e) {
                    System.out.println("数据异常,跳过: " + u.getUsername());
                    continue; // 继续处理下一条数据
                }
            }
            session.commit();
        }
    }
}

常见问题

新手在刚接触MyBatis时,经常会遇到以下几个问题,我给大家整理了避坑指南:

常见问题 产生原因 解决方案
BindingException Mapper接口与XML文件没有正确绑定 检查XML中的namespace是否和接口全限定名完全一致。
查询结果全为null 数据库字段名与实体类属性名不一致 在XML中使用<resultMap>进行字段映射,或在SQL中使用as起别名。
SqlSession未关闭导致连接泄漏 忘记在finally块中关闭会话 强烈建议使用try-with-resources语法糖来自动关闭SqlSession
插入数据后数据库没变化 增删改操作没有提交事务 MyBatis默认不自动提交事务,需在代码中手动调用session.commit()

学习建议

掌握了以上基础,你已经算正式迈入了MyBatis的大门。对于下一步的学习路径,我建议大家按照以下顺序进阶:

  1. 掌握动态SQL:学习<if><choose><foreach>等标签,这是应对复杂查询条件的利器。
  2. 理解缓存机制:深入了解MyBatis的一级缓存和二级缓存,明白它们的作用域和失效场景。
  3. 整合Spring:在实际企业开发中,我们很少单独使用MyBatis,通常会结合Spring或SpringBoot,学习mybatis-spring的整合配置是必经之路。
  4. 阅读底层源码:当你用得很熟练后,尝试去阅读MyBatis的源码,特别是动态代理和SQL解析的部分,这会让你的技术深度产生质的飞跃。

编程是一场马拉松,不要急于求成。多动手敲代码,多思考背后的原理,你一定能成为一名优秀的后端工程师。祝大家学习愉快!

评论 0

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