MyBatis 动态SQL详解
本文主要介绍MyBatis动态SQL支持根据不同条件灵活构建SQL语句。1. 什么是动态 SQL重要知识点定义动态 SQL 是 MyBatis 的强大特性之一它允许在 SQL 语句中根据不同的条件动态地生成不同的 SQL 片段从而实现更灵活的数据库操作。应用场景在实际开发中经常会遇到根据不同的查询条件生成不同的 SQL 语句的情况如多条件查询、动态更新等。使用动态 SQL 可以避免硬编码 SQL 语句提高代码的可维护性和灵活性。MyBatis动态SQL是其强大特性之一允许你根据不同条件生成不同的SQL语句。以下是MyBatis中常用的动态SQL标签及其用法1.if标签作用条件判断类似于Java中的if语句。用法常用于WHERE子句、SET子句中避免硬编码。selectidfindUserresultTypeUserSELECT * FROM users WHERE 11iftestusername ! null and username ! AND username #{username}/ififtestage ! nullAND age #{age}/if/select说明test属性为必填项支持OGNL表达式如username ! null。需注意SQL语法例如示例中的WHERE 11避免条件全不满足时的语法错误。2.choose、when、otherwise标签作用类似于Java中的switch-case-default语句多个条件中选择一个执行。用法当多个条件互斥时使用。selectidfindUserByConditionresultTypeUserSELECT * FROM users WHERE 11choosewhentestusername ! nullAND username #{username}/whenwhentestemail ! nullAND email #{email}/whenotherwiseAND age 18/otherwise/choose/select说明choose为父标签内部包含多个when和一个可选的otherwise。按顺序判断when的test条件满足则执行并跳过后续条件。3.where标签作用智能处理WHERE子句自动剔除多余的AND、OR。用法替代手动编写WHERE 11。selectidfindUserresultTypeUserSELECT * FROM userswhereiftestusername ! nullusername #{username}/ififtestage ! nullAND age #{age}/if/where/select说明如果where内的条件全不满足则不会生成WHERE子句。自动剔除第一个条件前的AND或OR。4.set标签作用智能处理UPDATE语句的SET子句自动剔除多余的逗号。用法动态更新字段。updateidupdateUserUPDATE userssetiftestusername ! nullusername #{username},/ififtestemail ! nullemail #{email},/ififtestage ! nullage #{age}/if/setWHERE id #{id}/update说明自动剔除最后一个条件后的逗号。至少需要一个条件满足否则会导致语法错误。5.foreach标签作用循环处理集合参数如List、Array、Map常用于IN条件或批量操作。用法通过collection、item、index、open、separator、close属性配置。!-- IN条件示例 --selectidfindUsersByIdsresultTypeUserSELECT * FROM users WHERE id INforeachcollectionidsitemidopen(separator,close)#{id}/foreach/select!-- 批量插入示例 --insertidinsertUsersINSERT INTO users (username, age) VALUESforeachcollectionlistitemuserseparator,(#{user.username}, #{user.age})/foreach/insert属性说明collection集合类型如list、array、map.keys。item迭代变量名。open/close输出的首尾字符。separator元素间的分隔符。6.trim标签作用自定义前缀、后缀以及前缀后缀的剔除规则可替代where、set。用法通过prefix、suffix、prefixOverrides、suffixOverrides属性配置。!-- 替代where --trimprefixWHEREprefixOverridesAND |OR...条件语句/trim!-- 替代set --trimprefixSETsuffixOverrides,...SET语句/trim属性说明prefix/suffix添加前缀/后缀。prefixOverrides/suffixOverrides剔除匹配的前缀/后缀字符串。7.sql和include标签作用提取公共SQL片段提高复用性。用法通过sql定义片段include引用。!-- 定义公共片段 --sqliduserColumnsid, username, email, age/sql!-- 引用片段 --selectidfindAllUsersresultTypeUserSELECTincluderefiduserColumns/FROM users/select说明refid为sql的id支持跨映射文件引用需加命名空间。8.bind标签作用通过OGNL表达式创建一个变量并绑定到上下文常用于模糊查询。用法避免SQL注入替代LIKE %${value}%。selectidfindUserByUsernameresultTypeUserbindnamepatternvalue% username %/SELECT * FROM users WHERE username LIKE #{pattern}/select动态SQL示例复杂查询selectidsearchUsersresultTypeUserSELECT * FROM userswhereiftestkeyword ! null and keyword ! bindnamekeyLikevalue% keyword %/AND (username LIKE #{keyLike} OR email LIKE #{keyLike})/ififtestageRange ! null and ageRange.size() 2AND age BETWEEN #{ageRange[0]} AND #{ageRange[1]}/ififteststatusList ! null and statusList.size() 0AND status INforeachcollectionstatusListitemstatusopen(separator,close)#{status}/foreach/if/wherechoosewhentestsort ageORDER BY age DESC/whenotherwiseORDER BY create_time DESC/otherwise/choose/select总结MyBatis动态SQL通过标签灵活拼接SQL语句避免硬编码提高代码复用性。核心是根据参数动态生成SQL常用场景包括条件查询、动态更新、批量操作等。使用时需注意SQL注入优先使用#{}占位符避免${}直接拼接。语法正确性动态生成的SQL需符合数据库语法如空条件、多余逗号。性能复杂动态SQL可能影响可读性和性能必要时可拆分为多个简单SQL。