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

119 阅读5分钟

TL;DR

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

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

版本矩阵

功能状态说明
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 快速入门

MyBatis 官方文档页面:包含 Introduction、What is MyBatis、多语言翻译选项

官方地址

http://www.mybatis.org/mybatis-3/

MyBatis 官方网站截图:展示 MyBatis 权威资源入口

开发步骤

  • 添加 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 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>

数据表

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

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;

对应的表如下所示:

Navicat 数据库表设计界面:展示 user_info 表结构,包含 id(主键)、username、password、age 四个字段

实体类

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;
}

对应的截图如下所示:

IntelliJ IDEA 代码编辑器:展示 UserInfo 实体类,使用 Lombok @Data 注解,包含 id、username、password、age 四个属性

Mapper

<?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>

对应的截图如下所示:

MyBatis Mapper XML 编辑器:展示 UserInfoMapper.xml 映射文件,包含 selectOne 和 selectList 两个查询语句的 SQL 配置

核心文件

<?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>

对应的截图如下所示:

IntelliJ IDEA XML 配置编辑器:展示 MyBatis 核心配置文件 sqlMapConfig.xml,包含数据库连接属性、数据源配置(POOLED)和 Mapper 映射文件路径

测试代码

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();
    }
}

控制台输出结果如下:

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.

执行结果如下图所示:

IntelliJ IDEA 运行窗口:展示 MyBatis 执行结果,左侧为项目结构,右侧为控制台输出,显示 DEBUG 日志和查询结果 UserInfo(id=1, username=wzk, password=icu, age=18)


错误速查卡

症状根因定位修复
BindingException: Type interface xxx is not knownMapper 接口未注册检查 XML namespace 是否与接口全限定名匹配确保 namespace="icu.wzk.mapper.UserInfoMapper"
Property 'driverClass' not foundproperties 占位符未定义检查 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 valueSQL 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 rowSQL 返回多条结果但用 selectOne检查 SQL 是否需要加 LIMIT 1确认查询条件唯一性或改用 selectList
log4j 日志不输出日志配置缺失检查是否配置了 Log4j 或 SLF4j添加 log4j.properties 或 log4j.xml 配置文件
数据库连接不上JDBC URL/用户名/密码错误检查 sqlMapConfig.xml 中的数据库连接信息确认 MySQL 服务运行中,IP/端口/数据库名正确

作者:武子康的个人博客