Java-02 深入浅出MyBatis 3 快速入门:环境配置、项目创建与 CRUD 操作

TL;DR

  • 场景:Java 开发者学习 MyBatis 3 框架的入门教程
  • 结论:MyBatis 通过 Mapper XML 和接口映射实现半自动 ORM,支持动态 SQL 和注解配置,Maven 依赖管理简单易用
  • 产出:完整的 MyBatis 项目搭建步骤、POM 配置、Mapper 编写、核心配置文件示例

版本矩阵

功能 状态 说明
MyBatis 3.4.5 依赖 ✅ 已验证 Maven pom.xml 配置
MySQL 驱动 5.1.6 ✅ 已验证 mysql-connector-java
Lombok 注解 ✅ 已验证 @Data @Builder 配置
Mapper XML 映射 ✅ 已验证 namespace + CRUD 语句
SqlMapConfig.xml 配置 ✅ 已验证 properties + environments + mappers
SqlSessionFactory 构建 ✅ 已验证 Resources.getResourceAsStream
selectList 查询 ✅ 已验证 返回 List 结果
Log4j 日志 ✅ 已验证 DEBUG 日志输出

MyBatis 快速入门

官方地址

shell 复制代码
http://www.mybatis.org/mybatis-3/

开发步骤

  • 添加 MyBatis 的坐标
  • 创建 User 数据表
  • 编写 User 实体类
  • 编写映射文件 UserMapper
  • 编写核心文件 SqlMapConfig.xml
  • 编写测试类

创建数据库和表

  • 根据项目需求设计数据库表。
  • 编写 SQL 脚本创建表结构。

导入 MyBatis 依赖

如果使用 Maven 管理项目,添加 MyBatis 的依赖。

例如,常见的依赖包括 MyBatis 核心库、MyBatis-Spring(若结合 Spring 使用)和数据库驱动。

项目结构规划

在项目中,通常会按照以下结构组织代码:

  • Mapper 文件夹:存放 MyBatis 的映射接口文件。
  • Mapper XML 文件夹:存放 MyBatis 的 SQL 映射文件。
  • 实体类文件夹:对应数据库表的 Java 实体类。
  • Service 文件夹:封装业务逻辑。
  • DAO(或 Repository)文件夹:封装数据库操作。

配置主配置文件 mybatis-config.xml

  • 配置数据库连接信息(或者直接通过外部 DataSource 配置)。
  • 配置别名,简化实体类的全类名使用。
  • 指定 Mapper XML 文件的路径。

数据库连接配置

  • 配置数据库连接的 URL、用户名、密码等信息。
  • 如果结合 Spring 或 Spring Boot 使用,可以直接通过 DataSource Bean 注入。

创建实体类

  • 根据数据库表结构创建与之对应的 Java 实体类。
  • 属性名与表中的字段名保持一致(建议使用驼峰命名)。
  • 可以使用注解 @Alias 设置别名。

编写 Mapper 接口

  • 创建 Mapper 接口,用于声明操作数据库的方法。
  • 方法名与 SQL 映射文件中的 id 一一对应。
  • Mapper 接口上无需实现类,MyBatis 会动态生成实现。

编写 Mapper 映射文件

编写与 Mapper 接口方法对应的 SQL。

定义 SQL 语句的 id,以供 Mapper 接口调用。

常用标签包括:

  • select:查询语句。
  • insert:插入语句。
  • update:更新语句。
  • delete:删除语句。

动态 SQL 功能:使用 <if><choose> 等标签构建复杂查询条件。

加载配置文件

  • 使用 SqlSessionFactoryBuilder 读取 mybatis-config.xml,构建 SqlSessionFactory。
  • 通过 SqlSessionFactory 获取 SqlSession,执行 Mapper 方法。

POM

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>mybatis-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!--mybatis坐标-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!--mysql驱动坐标-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
            <scope>runtime</scope>
        </dependency>
        <!--单元测试坐标-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--日志坐标-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
    </dependencies>

</project>

数据表

新建一个数据库,放一张测试的表进去。

sql 复制代码
CREATE TABLE `user_info` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `money` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

对应的表如下所示:

实体类

java 复制代码
package icu.wzk.model;


import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserInfo {
    private Long id;
    private String username;
    private String password;
    private Integer age;
}

对应的截图如下所示:

Mapper

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="icu.wzk.mapper.UserInfoMapper">
    <!-- 查询单个用户信息 -->
    <select id="selectOne" parameterType="java.lang.String" resultType="icu.wzk.model.UserInfo">
        SELECT
            *
        FROM
            user_info
        WHERE
            username = #{username}
    </select>
    <!-- 查询所有用户信息 -->
    <select id="selectList" resultType="icu.wzk.model.UserInfo">
        SELECT
            *
        FROM
            user_info
    </select>
</mapper>

对应的截图如下所示:

核心文件

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>
    <properties>
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://172.16.1.130:3306/wzk-mybatis?characterEncoding=utf-8"/>
        <property name="user" value="hive"/>
        <property name="password" value="hive@wzk.icu"/>
    </properties>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driverClass}"/>
                <property name="url" value="${jdbcUrl}"/>
                <property name="username" value="${user}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mapper.xml"/>
    </mappers>
</configuration>

对应的截图如下所示:

测试代码

java 复制代码
package icu.wzk;

import icu.wzk.model.UserInfo;
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.IOException;
import java.io.InputStream;
import java.util.List;

public class WzkIcu01 {
    public static void main(String[] args) throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<UserInfo> dataList = sqlSession.selectList("icu.wzk.mapper.UserInfoMapper.selectList");
        dataList.forEach(System.out::println);
        sqlSession.close();
    }
}

控制台输出结果如下:

shell 复制代码
24/11/11 15:02:49 DEBUG logging.LogFactory: Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
24/11/11 15:02:49 DEBUG pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.
24/11/11 15:02:49 DEBUG pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.
24/11/11 15:02:49 DEBUG pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.
24/11/11 15:02:49 DEBUG pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.
24/11/11 15:02:49 DEBUG jdbc.JdbcTransaction: Opening JDBC Connection
24/11/11 15:02:49 DEBUG pooled.PooledDataSource: Created connection 240166646.
24/11/11 15:02:49 DEBUG jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@e50a6f6]
24/11/11 15:02:49 DEBUG UserInfoMapper.selectList: ==>  Preparing: SELECT * FROM user_info
24/11/11 15:02:49 DEBUG UserInfoMapper.selectList: ==> Parameters:
24/11/11 15:02:49 DEBUG UserInfoMapper.selectList: <==      Total: 1
UserInfo(id=1, username=wzk, password=icu, age=18)
24/11/11 15:02:49 DEBUG jdbc.JdbcTransaction: Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@e50a6f6]
24/11/11 15:02:49 DEBUG jdbc.JdbcTransaction: Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@e50a6f6]
24/11/11 15:02:49 DEBUG pooled.PooledDataSource: Returned connection 240166646 to pool.

执行结果如下图所示:


错误速查卡

症状 根因 定位 修复
BindingException: Type interface xxx is not known Mapper 接口未注册 检查 XML namespace 是否与接口全限定名匹配 确保 namespace="icu.wzk.mapper.UserInfoMapper"
Property 'driverClass' not found properties 占位符未定义 检查 sqlMapConfig.xml 中 properties 是否正确定义 添加 <property name="driverClass" value="..."/>
java.io.IOException: Could not find sqlMapConfig.xml 资源文件路径错误 检查 Resources.getResourceAsStream 参数 确保 sqlMapConfig.xml 在 classpath 根目录
Mapped Statement collection does not contain value SQL id 不匹配 检查 Mapper XML 中的 id 是否与接口方法名一致 确保 select id="selectList" 与接口方法名一致
Invalid bound statement (not found) Mapper XML 路径未注册 检查 <mappers> 配置是否包含该 XML 添加 <mapper resource="mapper.xml"/>
Could not get a single row SQL 返回多条结果但用 selectOne 检查 SQL 是否需要加 LIMIT 1 确认查询条件唯一性或改用 selectList
log4j 日志不输出 日志配置缺失 检查是否配置了 Log4j 或 SLF4j 添加 log4j.properties 或 log4j.xml 配置文件
数据库连接不上 JDBC URL/用户名/密码错误 检查 sqlMapConfig.xml 中的数据库连接信息 确认 MySQL 服务运行中,IP/端口/数据库名正确

作者:武子康的个人博客

相关推荐
折哥的程序人生 · 物流技术专研4 分钟前
《Java 100 天进阶之路》第93篇:Redis实战应用:缓存策略与分布式锁(2026版)
java·redis·缓存·面试·架构·求职招聘
瓦特what?5 分钟前
位运算核心技巧与应用
java·jvm·算法
人道领域7 分钟前
【LeetCode刷题日记】90.子集Ⅱ--- 归纳题解
java·开发语言·leetcode
sandnes11 分钟前
把ToolUse循环做到生产级-错误处理与可靠性五件套
后端
ch.ju13 分钟前
Java Programming Chapter 4——Characteristics of inheritance
java·开发语言
就叫_这个吧15 分钟前
tomcat在idea控制台乱码问题解决
java·tomcat·intellij-idea
掘金者阿豪21 分钟前
全维度拆解具身智能:底层技术 + 实战落地 + 全球产业竞争
后端
霸道流氓气质24 分钟前
Spring AI Alibaba Skills 完整实战:从零构建智能会议助手
java·人工智能·spring
秋天的一阵风25 分钟前
✨ 代码秒跳转、自动补全?全靠 LSP 和 AST!
前端·后端·ai编程
极客先躯35 分钟前
高级java每日一道面试题-2026年02月04日-实战篇[Docker]-如何在容器之间共享数据?
java·运维·网络·docker·容器·自动化·高级面试题