详解MyBatis 动态 SQL
个人主页:一条泥憨鱼(欢迎各位大佬莅临)精选专栏:数据结构与算法JavaSE ,苍穹外卖日记AI学习前言在学习 JavaWeb 或企业级开发时很多同学都会遇到一个问题“查询条件不固定SQL 语句到底该怎么写”比如用户可能输入用户名也可能不输入商品查询可能按价格、分类、库存组合搜索更新用户信息时有些字段可能为空如果全靠字符串拼接 SQL不但代码难看而且容易出错。于是MyBatis 提供了一个非常强大的功能动态 SQL它可以让 SQL “像程序一样”动态变化。这篇文章会带你从零开始彻底搞懂 MyBatis 动态 SQL。一、什么是动态 SQL先看一个普通 SQLSELECT * FROM user WHERE username Tom;但现实中用户名可能为空。那么 SQL 就需要动态变化SELECT * FROM user;或者SELECT * FROM user WHERE username Tom;这就是SQL 根据条件动态变化MyBatis 提供了很多标签帮助我们实现这种功能。最常用的有标签作用if条件判断where自动处理 WHEREset自动处理 UPDATEforeach循环遍历choose类似 switchtrim自定义拼接规则二、为什么需要动态 SQL如果不用动态 SQL代码会非常麻烦。例如String sql select * from user where 11; if(username ! null){ sql and username #{username}; } if(age ! null){ sql and age #{age}; }问题很多可读性差SQL 拼接容易出错不方便维护容易产生 SQL 注入风险MyBatis 动态 SQL 可以优雅解决这些问题。三、准备工作假设有一张用户表CREATE TABLE user( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50), age INT, gender VARCHAR(10) );对应实体类public class User { private Integer id; private String username; private Integer age; private String gender; // getter/setter }Mapper接口public interface UserMapper { ListUser select(User user); }四、if标签这是最常用的动态 SQL 标签。作用条件成立时才拼接 SQL1、基本使用select idselect resultTypeUser SELECT * FROM user WHERE 11 if testusername ! null AND username #{username} /if if testage ! null AND age #{age} /if /select2、执行效果情况1User user new User(); user.setUsername(Tom);生成 SQLSELECT * FROM user WHERE 11 AND username Tom情况2User user new User(); user.setAge(20);生成 SQLSELECT * FROM user WHERE 11 AND age 20五、where标签很多初学者都会写WHERE 11虽然能用但不优雅。MyBatis 提供了where它能自动添加 WHERE去掉多余的 AND1、改造代码select idselect resultTypeUser SELECT * FROM user where if testusername ! null AND username #{username} /if if testage ! null AND age #{age} /if /where /select2、效果如果没有任何条件SELECT * FROM user如果有条件SELECT * FROM user WHERE username Tom是不是优雅很多六、set标签用于动态更新 SQL1、需求用户修改信息时只修改传入的字段空字段不更新2、代码实现update idupdateUser UPDATE user set if testusername ! null username #{username}, /if if testage ! null age #{age}, /if if testgender ! null gender #{gender}, /if /set WHERE id #{id} /update3、作用set会自动添加 SET去掉最后一个逗号4、生成 SQLUPDATE user SET username Tom, age 20 WHERE id 1七、foreach标签这是开发中非常重要的标签。作用循环遍历集合最经典的场景批量查询1、需求查询多个 IDSELECT * FROM user WHERE id IN (1,2,3)2、Mapper接口ListUser selectByIds(ListInteger ids);3、XML写法select idselectByIds resultTypeUser SELECT * FROM user where foreach collectionlist itemid openid IN ( separator, close) #{id} /foreach /where /select4、参数解释属性作用collection集合名称item每次遍历元素open开始字符串separator分隔符close结束字符串5、生成 SQLSELECT * FROM user WHERE id IN (1,2,3)八、choose标签类似 Java 中的switch-case作用多选一示例select idselect resultTypeUser SELECT * FROM user where choose when testusername ! null username #{username} /when when testage ! null age #{age} /when otherwise gender 男 /otherwise /choose /where /select逻辑username 有值 → 按 username 查询否则 age 有值 → 按 age 查询都没有 → 默认查询 gender男九、trim标签这是一个高级标签。作用自定义字符串拼接规则示例trim prefixWHERE prefixOverridesAND |OR if testusername ! null AND username #{username} /if if testage ! null AND age #{age} /if /trim含义属性作用prefix添加前缀prefixOverrides删除前缀suffix添加后缀suffixOverrides删除后缀实际上where底层本质上就是trim的封装。十、动态 SQL 执行流程很多同学会问MyBatis 是怎么让 SQL 动态变化的流程如下XML动态SQL ↓ MyBatis解析标签 ↓ 拼接最终SQL ↓ 预编译SQL ↓ 执行数据库操作所以动态 SQL 本质上是 SQL 的动态拼接但它比手写字符串安全得多。十一、动态 SQL 的开发技巧1、优先使用where不要再WHERE 11了。2、更新操作使用set避免age 20,最后多逗号报错。3、批量操作一定学会foreach企业开发中极其常见。例如批量删除批量查询批量插入4、避免 SQL 过于复杂动态 SQL 很强大但不要把所有业务逻辑都写进 SQL否则后期维护会非常痛苦。十二、完整案例多条件查询Mapper接口ListUser selectCondition(User user);XMLselect idselectCondition resultTypeUser SELECT * FROM user where if testusername ! null and username ! AND username LIKE CONCAT(%,#{username},%) /if if testage ! null AND age #{age} /if if testgender ! null AND gender #{gender} /if /where /select测试代码User user new User(); user.setUsername(o); user.setGender(男); ListUser users mapper.selectCondition(user); users.forEach(System.out::println);生成 SQLSELECT * FROM user WHERE username LIKE %o% AND gender 男十三、动态 SQL 常见面试题1、动态 SQL 有哪些标签常见ifwheresetforeachchoosetrim2、where有什么作用自动添加 WHERE删除多余 AND/OR3、set有什么作用自动添加 SET删除最后逗号4、#{}和${}区别#{}预编译WHERE id ?安全推荐使用。${}字符串拼接ORDER BY age存在 SQL 注入风险。十四、总结动态 SQL 是 MyBatis 中最核心的能力之一。掌握后你就能真正写出灵活的查询动态更新批量操作企业级 SQL重点回顾标签核心作用if条件判断where自动处理 WHEREset动态更新foreach循环集合choose多选一trim自定义拼接很多初学者觉得“动态 SQL 好复杂。”“根据条件动态拼接 SQL。”只要理解这一点你就已经入门了。今天的学习就暂时告一段落啦如果文章对您有用的话还请留下一个免费的小心心和关注哦祝您工作顺利生活愉快。我们下期再见