Spring Boot 整合 MyBatis 中使用 XML 标签实现动态 SQL 的完整指南

💡 一、前言

在现代 Java Web 开发中,MyBatis 凭借其灵活性和高性能,成为众多开发者首选的 ORM 框架。而在 Spring Boot 项目中整合 MyBatis 后,合理使用其 XML 中的各种标签,不仅能简化数据库操作,还能提升代码可读性和维护性。

本文将深入讲解 MyBatis 提供的核心 XML 标签,结合实际业务场景,帮助你掌握从基础到高级的动态 SQL 编写技巧

(如果不太了解SpringBoot整合MyBatis的可以访问从零开始,手把手教你 Spring Boot 如何整合 MyBatis(超详细图文教程))。


🛠️ 二、环境准备

1. 添加依赖(pom.xml)

<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- MyBatis Starter -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.2</version>
    </dependency>

    <!-- MySQL 驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

2. 配置数据源(application.yml)

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test_db
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.example.demo.model

📄 三、MyBatis 常用标签详解与实战

✅ 1. <if> 标签:条件判断

场景:根据用户输入的姓名和年龄进行模糊查询。
<select id="findUsers" resultType="User">
    SELECT * FROM users
    WHERE 1=1
    <if test="name != null and name != ''">
        AND name LIKE CONCAT('%', #{name}, '%')
    </if>
    <if test="age != null">
        AND age >= #{age}
    </if>
</select>

✅ 2. <choose>/<when>/<otherwise>:多条件选择

场景:优先按名称查询,没有名称则按年龄范围查询,都无则返回所有。
<select id="findUsersByChoose" resultType="User">
    SELECT * FROM users
    <where>
        <choose>
            <when test="name != null">
                name LIKE CONCAT('%', #{name}, '%')
            </when>
            <when test="minAge != null and maxAge != null">
                age BETWEEN #{minAge} AND #{maxAge}
            </when>
            <otherwise>
                1=1
            </otherwise>
        </choose>
    </where>
</select>

✅ 3. <where> 标签:智能拼接 WHERE 子句

该标签会自动处理 ANDOR 开头的问题,避免 SQL 语法错误。

<select id="searchUsers" resultType="User">
    SELECT * FROM users
    <where>
        <if test="name != null">
            name LIKE CONCAT('%', #{name}, '%')
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>

✅ 4. <set> 标签:更新操作时自动去除尾部逗号

场景:根据 ID 更新用户信息,仅更新非空字段。
<update id="updateUser">
    UPDATE users
    <set>
        <if test="name != null">name = #{name},</if>
        <if test="age != null">age = #{age}</if>
    </set>
    WHERE id = #{id}
</update>

✅ 5. <foreach> 标签:遍历集合或数组

场景:批量插入用户信息
<insert id="batchInsertUsers">
    INSERT INTO users (name, age)
    VALUES
    <foreach collection="users" item="user" separator=",">
        (#{user.name}, #{user.age})
    </foreach>
</insert>

✅ 6. <trim> 标签:灵活控制前后缀

适用于更复杂的 SQL 拼接逻辑,比如手动控制 WHERESETAND 等关键字。

<select id="dynamicQuery" resultType="User">
    SELECT * FROM users
    <trim prefix="WHERE" prefixOverrides="AND |OR ">
        <if test="name != null">
            name LIKE CONCAT('%', #{name}, '%')
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </trim>
</select>

✅ 7. <sql><include> 标签:复用 SQL 片段

场景:定义通用字段或子查询,减少重复代码。
<sql id="base_columns">id, name, age, email</sql>

<select id="getUserById" resultType="User">
    SELECT <include refid="base_columns"/> FROM users WHERE id = #{id}
</select>

也可以带参数传递:

<sql id="condition_by_name">
    <if test="name != null">
        AND name LIKE CONCAT('%', #{name}, '%')
    </if>
</sql>

<select id="searchUsersWithCondition">
    SELECT * FROM users
    WHERE 1=1
    <include refid="condition_by_name"/>
</select>

✅ 8. <bind> 标签:绑定变量表达式

场景:提前处理参数,提高 SQL 可读性。
<select id="searchByName" resultType="User">
    <bind name="pattern" value="'%' + name + '%'" />
    SELECT * FROM users WHERE name LIKE #{pattern}
</select>

🧪 四、测试接口与 Controller 示例

Mapper 接口:

@Mapper
public interface UserMapper {
    public List<User> findUsers(@Param("name")String name,@Param("age") Integer age);
    
    public int batchInsertUsers(@Param("users") List<User> users);
    
    public int updateUser(User user);
}

Controller 示例:

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserMapper userMapper;

    @GetMapping("/search")
    public List<User> searchUsers(
        @RequestParam(required = false) String name,
        @RequestParam(required = false) Integer age) {
        return userMapper.findUsers(name, age);
    }

    @PostMapping("/batch")
    public void addUsers(@RequestBody List<User> users) {
        userMapper.batchInsertUsers(users);
    }
}

🔍 五、常见问题与调试技巧

问题描述解决方案
参数未生效或为空使用 @Param 注解明确传参名
SQL 报错开头为ANDOR使用 <where> 自动处理
批量插入失败检查数据库是否开启允许一次执行多个值插入
末尾有逗号报错MyBatis 会自动处理,无需手动删除

📘 六、最佳实践总结

标签使用场景建议
<if>单个条件筛选结合 <where> 使用效果更佳
<choose> 多选一条件更适合复杂条件分支
<where> 构建 WHERE 子句自动处理首尾多余的关键字
<set> 构建 SET 子句更新部分字段非常有用
<foreach>遍历集合适用于 IN 查询、批量插入等
<trim>灵活控制 SQL 片段当其他标签无法满足需求时使用
<sql>/<include> 复用 SQL提升代码复用率
<bind>绑定变量提高 SQL 可读性和灵活性

🧩 七、进阶技巧推荐

1. 分页 + 动态查询结合使用

<select id="searchUsersWithPage" resultType="User">
    SELECT * FROM users
    <where>
        <if test="name != null">
            name LIKE CONCAT('%', #{name}, '%')
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>

在 Service 层调用 PageHelper:

PageHelper.startPage(pageNum, pageSize);
List<User> users = userMapper.searchUsersWithPage(name, age);
return new PageInfo<>(users);

📝 八、结语

通过掌握 MyBatis 提供的各种 XML 标签,你可以轻松实现动态 SQL 构建,大大提升数据库操作的灵活性和可维护性。

希望这篇文章能帮助你更好地理解 MyBatis 中标签的使用方式。如果你觉得有用,欢迎点赞、收藏、转发给更多需要的朋友!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值