找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1583

积分

0

好友

202

主题
发表于 2026-1-3 12:32:31 | 查看: 21| 回复: 0

在 Java 后端开发中,MyBatis 以其 灵活的 SQL 控制低侵入性,始终是最主流的持久层框架之一。Spring Boot 通过 MyBatis-Spring-Boot-Starter 提供了“开箱即用”的自动化配置,让整合过程变得极为简单。而面对 MyBatis 最核心的两种开发方式——注解方式XML 配置方式,开发者应如何根据业务场景做出选择?本文将从环境配置讲起,详细解析两种方式的核心用法、适用场景,并深入探讨 MyBatis 的灵魂功能:动态 SQL。

一、快速整合:MyBatis-Spring-Boot-Starter 配置

得益于 Spring Boot 强大的自动配置机制,整合 MyBatis 无需再编写繁琐的 XML 配置文件,仅需简单几步即可完成项目搭建。

1. 核心依赖引入

在项目的 pom.xml 文件中,引入 MyBatis-Spring-Boot-Starter 及相应的数据库驱动依赖。Spring Boot 会自动管理 MyBatis 核心包、Spring 整合包等相关依赖的版本。

<dependencies>
    <!-- Spring Boot Web依赖(可选,用于接口测试) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- MyBatis Spring Boot Starter核心依赖 -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.3.2</version> <!-- 版本需适配Spring Boot,请根据实际情况调整 -->
    </dependency>

    <!-- MySQL驱动 -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>

    <!-- Lombok(用于简化实体类代码,可选) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

2. 核心配置参数

application.yml 中配置数据库连接信息及 MyBatis 专属参数,这是控制 MyBatis 行为的关键。

spring:
  # 数据库连接配置
  datasource:
    url: jdbc:mysql://localhost:3306/mybatis_demo?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis:
  # 1. XML方式核心配置:指定Mapper XML文件路径(默认扫描resources/mybatis/mapper/**)
  mapper-locations: classpath:mybatis/mapper/*.xml
  # 2. 配置别名:指定实体类所在包,XML中可直接使用类名(无需全限定名)
  type-aliases-package: com.example.mybatis.entity
  # 3. 驼峰命名自动转换(数据库下划线命名 -> Java驼峰命名)
  configuration:
    map-underscore-to-camel-case: true
    # 打印SQL语句(开发环境开启,便于调试)
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

关键配置说明

  • mapper-locations:仅用于 XML 方式,指定 Mapper XML 文件的存放路径,支持通配符。
  • type-aliases-package:配置后,在 XML 映射文件中引用实体类时可直接写 User,而无需写全限定名 com.example.mybatis.entity.User
  • map-underscore-to-camel-case:开启后,数据库表的 user_name 字段会自动映射到 Java 实体类的 userName 属性,极大减少了手动编写结果映射的工作。

3. 核心注解:@Mapper 与 @MapperScan

配置完成后,需要让 Spring 容器能够扫描并管理 MyBatis 的 Mapper 接口。这里有两种常用方式:

  • @Mapper 注解:直接在 Mapper 接口上添加。适用于 Mapper 接口数量较少的项目。
  • @MapperScan 注解:在 Spring Boot 主启动类上添加,指定 Mapper 接口所在的包路径,进行批量扫描。这是更推荐的方式,尤其适用于大型项目。

以下是 @MapperScan 的用法示例:

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.mybatis.mapper") // 扫描指定包下的所有Mapper接口
public class MyBatisApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyBatisApplication.class, args);
    }
}

二、两种开发方式对比:注解方式 vs XML 配置方式

MyBatis 提供了注解和 XML 两种将 SQL 与 Java 代码关联的模式,其核心差异在于 SQL 的存放位置。选择哪种方式,直接关系到代码的可读性、可维护性和开发效率。

1. 注解方式:简洁高效,适合简单 SQL

注解方式直接将 SQL 语句编写在 Mapper 接口方法的注解中,无需额外的 XML 文件,使得开发流程非常高效。

(1)核心注解及用法
常用注解与 XML 标签一一对应:

  • @Select:对应 <select> 标签,用于查询操作。
  • @Insert:对应 <insert> 标签,用于新增操作。
  • @Update:对应 <update> 标签,用于更新操作。
  • @Delete:对应 <delete> 标签,用于删除操作。
  • @Results:用于自定义结果集映射(开启驼峰转换后通常可省略)。
  • @Param:为方法参数指定名称,以便在 SQL 中引用。

(2)核心优势与适用场景

  • 优势:开发快捷,SQL 与 Java 代码位于同一文件,一目了然;减少了文件数量。
  • 劣势:编写复杂 SQL(如多表关联、动态条件)时,注解内容会变得冗长混乱,可读性和可维护性急剧下降。
  • 适用场景:简单的单表 CRUD 操作、业务逻辑不复杂的查询。

2. XML 配置方式:灵活强大,适合复杂 SQL

XML 方式将 SQL 独立存放在 .xml 文件中,通过结构化的标签来组织 SQL 逻辑,是 MyBatis 最经典、功能最全面的使用方式。

(1)核心 XML 标签
除了基础的增删改查标签,XML 方式提供了更强大的标签集:

  • 基础标签<select>, <insert>, <update>, <delete>
  • 结果映射标签<resultMap>,支持复杂的对象关联映射(一对一、一对多)。
  • 动态 SQL 标签<if>, <where>, <foreach>, <choose> 等,这是 XML 方式的核心竞争力。

(2)核心优势与适用场景

  • 优势:SQL 与 Java 代码完全解耦,便于 DBA 评审或统一管理;原生支持强大、直观的动态 SQL;格式工整,可读性极佳。
  • 劣势:需要额外创建和维护 XML 文件,开发步骤稍多。
  • 适用场景:复杂的多表关联查询、包含大量动态条件的搜索、批量操作、存储过程调用等。对于生产环境的复杂项目,强烈推荐使用 XML 方式。

3. 两种方式核心对比表

特性 注解方式 XML 配置方式
SQL 存放位置 Java 接口的注解中 独立的 XML 文件中
开发效率 高,无需维护 XML 稍低,需维护额外文件
复杂 SQL 支持 弱,编写繁琐、可读性差 ,原生支持动态 SQL、多表关联
代码解耦 差,SQL 与 Java 代码耦合 ,SQL 与 Java 代码完全分离
可读性 简单 SQL 尚可,复杂 SQL 差 ,格式规范,逻辑清晰
推荐适用场景 简单 CRUD、单表查询 复杂查询、多表关联、动态条件查询

三、动态 SQL 编写:MyBatis 的核心优势

动态 SQL 是 MyBatis 的灵魂功能。它允许根据运行时参数动态地拼接 SQL 语句,彻底避免了在 Java 代码中进行繁琐且易错的字符串拼接。虽然两种方式都支持动态 SQL,但 XML 方式的实现更加直观和强大

1. 核心动态 SQL 标签(XML 方式)

XML 提供了一系列专属标签来优雅地构建动态 SQL。

(1)<if>:条件判断
根据参数是否存在,动态添加 SQL 片段。

<select id="queryUserByCondition" resultType="User">
    SELECT id, user_name, email, age FROM t_user
    WHERE 1=1
    <if test="username != null and username != ''">
        AND user_name LIKE CONCAT('%', #{username}, '%')
    </if>
    <if test="age != null">
        AND age = #{age}
    </if>
</select>

(2)<where>:智能条件拼接
用来替代 WHERE 1=1 的写法,能智能地去除条件片段开头多余的 ANDOR,避免 SQL 语法错误。

<select id="queryUserByCondition" resultType="User">
    SELECT id, user_name, email, age FROM t_user
    <where>
        <if test="username != null and username != ''">
            user_name LIKE CONCAT('%', #{username}, '%')
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>

(3)<foreach>:循环遍历
用于 IN 查询或批量操作,遍历集合或数组参数。

<!-- 根据ID集合批量删除用户 -->
<delete id="batchDeleteUser">
    DELETE FROM t_user WHERE id IN
    <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</delete>
  • collection:方法中传入的集合或数组参数名。
  • item:遍历过程中每个元素的别名。
  • open/close:循环包装的开始和结束字符串。
  • separator:各元素之间的分隔符。

(4)<choose> + <when> + <otherwise>:分支选择
类似于 Java 中的 switch-caseif-else if-else 结构,只执行第一个满足条件的分支,适用于多条件互斥的场景。

<select id="queryUserByGrade" resultType="User">
    SELECT id, user_name, email, age FROM t_user
    <where>
        <choose>
            <when test="minAge != null and maxAge != null">
                age BETWEEN #{minAge} AND #{maxAge}
            </when>
            <when test="minAge != null">
                age >= #{minAge}
            </when>
            <when test="maxAge != null">
                age <= #{maxAge}
            </when>
            <otherwise>
                age > 18 <!-- 默认条件 -->
            </otherwise>
        </choose>
    </where>
</select>

2. 注解方式的动态 SQL

注解方式需要通过 @SelectProvider@InsertProvider 等 “Provider 注解” 来实现动态 SQL。它要求开发者编写一个额外的 Java 类,在其中用字符串拼接的方式构建 SQL。这种方式可读性差,且容易出错,仅建议在动态逻辑非常简单时使用。

// 1. 在Mapper接口中使用Provider注解
public interface UserMapper {
    @SelectProvider(type = UserSqlProvider.class, method = "queryUserByConditionSql")
    List<User> queryUserByCondition(@Param("username") String username, @Param("age") Integer age);
}

// 2. 编写SQL Provider类
public class UserSqlProvider {
    public String queryUserByConditionSql(@Param("username") String username, @Param("age") Integer age) {
        StringBuilder sql = new StringBuilder("SELECT id, user_name, email, age FROM t_user WHERE 1=1");
        if (username != null && !username.isEmpty()) {
            sql.append(" AND user_name LIKE CONCAT('%', #{username}, '%')");
        }
        if (age != null) {
            sql.append(" AND age = #{age}");
        }
        return sql.toString();
    }
}

四、核心总结

Spring Boot 与 MyBatis 的整合,核心在于利用自动配置简化环境搭建。而开发方式的选择,则应基于实际业务场景的复杂度进行权衡:

  1. 环境搭建三板斧:引入 mybatis-spring-boot-starter 依赖、配置数据库及 MyBatis 参数、使用 @MapperScan 扫描接口。
  2. 开发方式选择:追求开发效率的简单场景可选注解方式;注重灵活性、可维护性的复杂业务,务必选择 XML 配置方式
  3. 动态 SQL:这是 MyBatis 的立身之本,XML 方式通过 <if>, <where>, <foreach> 等标签提供了极其优雅的实现,是处理复杂查询条件的利器。

掌握这两种模式及其适用场景,你就能在 Java 持久层开发中游刃有余。MyBatis 的精髓在于将 SQL 的控制权交还给开发者,在保证性能优化的同时,又不失框架的便利性,这正是它区别于全自动 ORM(如 JPA)的核心价值所在。希望这篇实战指南能帮助你更好地理解和运用 MyBatis。如果你想深入探讨更多架构设计与技术细节,欢迎前往 云栈社区技术文档 板块,与更多开发者交流学习。




上一篇:RT-Thread创始人技术历程:从Linux情结到RTOS,及面向物联网的跨界思考
下一篇:实战指南:基于C#与海思SDK实现网络摄像头车牌识别
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-11 11:55 , Processed in 0.212325 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表