MyBatis 动态SQL的标签有哪些?如何使用? 目录1. MyBatis 动态SQL标签有什么用2. if 标签3. where 标签4. trim 标签5. choosewhenotherwise6. foreach一. MyBatis 动态SQL标签有什么用我来说一个场景大家就明白了如下图大家应该在铁路12306上买过火车票吧。可以看到在选票的时候可以对车做很多种筛选系统会自动根据用户的选择来匹配适应的车次其实它的底层就是采用的动态SQL拼接查询的方式完成的系统会根据用户不同的选择动态生成不同的SQL查询语句然后交给数据访问层去操作查询。下面我就来一个个介绍 MyBatis 框架给我们提供了哪些动态 SQL 拼接的标签。二. if 标签当我们实际开发多条件查询让用户选择的业务场景时也许用户不会把所有筛选条件都选上比如出去旅游在美团上订酒店可以按距离按价格按星级筛选也许用户不会把所有条件都选上可能只选一个但它也会查询出结果这个时候它就可以采用 if 标签生成动态SQL语句达到目的。if 标签可以通过它提供的 test 属性对数据内容做判断判断是否满足要求。若满足if 标签内部的内容就会执行反之则不执行。使用语法就是if test 判断条件 为true要执行的语句段 if示例如下代码所示// 在 mapper 映射文件中写我们的 SELECT 查询语句 // 这里if标签内不能使用Java中的 连接符mybatis 为我们提供了and关键字专门用来做连接操作 select idfindByNameAndAge resultTypeUser select * from user where 11 if testusername ! null and username ! and username #{username} /if if testage ! null and age ! and age #{age} /if /select // 这里我只是写了 username 和 age 连个字段实际开发过程中字段也许会很多 // 这里举例就写的简单一些其实都一样当有其他字段时继续追加 if 标签就可以了如上举例 if 标签我们可以在开发时就可以将用户不一定选择的查询条件使用 if 标签包裹起来test 双引号内部就是我们的判断条件不为空或者不为空字符串和 Java 中的 if 判断非常相似只有当 test 判断结果为 true即用户输入的结果不为空也不是空字符串说明用户输入的是有效数据就将用户想要查询的过滤条件加入到查询条件中如果为判断结果为 false则该字段的筛选条件不参与SQL语句中。这里有几个注意点我要提醒一下各位同学千万注意1在 where 条件的后面我们最好写一个恒成立的等式例如11222每个 if 标签内的字段前面都要加上一个 and因为如果 if 标签内的结果都不成立那么 SQL 语句就变成了 SELECT * FROM user WHERE 11。语法没有任何问题但如果我们不加11 查询语句就会变成 SELECT * FROM user WHERR。WHERE 查询条件后面没有任何东西就会出现语法级别的错误这是绝对不允许出现的为了避免此种情况我们可以在 WHERE后面加上一个恒成立条件使 WHERE 关键字无论何时都会起作用并且 SQL 语句语法不出错这是其中一点另外一点就是可以和我们 if 标签内的 and 完美连接。我举一个例子假设前端传递过来的数据 username 为空不满足条件那么 SQL 语句就变成了 SELECT * FROM user WHERE 11 and age #{age}。此时语法也没有任何问题并且可以和 and 关键字巧妙连接。不但解决了可能出现的 SQL 语法问题还解决了 and 关键字可能多余的情况。三. where 标签WHERE 标签的使用方式也很简单大多是搭配 if 使用的。使用方式 WHEREif 表标签内容/WHERE可以看到在我刚才 if 标签中我们将WHERE关键字写死了不管后面的 if 标签是否生效WHERE都会拼接到SQL语句中这样的写法有些死板而我们的 WHERE 标签就可以动态生成 WHERE 关键字。将刚才 if 中的代码修改后如下select idfindByNameAndAge resultTypeUser select * from user where if testusername ! null and username ! username #{username} /if if testage ! null and age ! and age #{age} /if /where /select我们只需要将所有的条件判断全部写到 WHERE 标签内部即可。1WHERE标签内只要有一个条件生效WHERE就会动态生成并拼接到SQL语句中2如果WHERE标签内部的都不执行那么WHERE也不会生成3WHERE 还可以智能地将语句前面多余的 and 删除也可以将 or 删除。4and 或 or 连接符只能写在字段判断的前面不能写在后面否则 WHERE 标签将无法自动智能删除只有写在前面才有效果例如我的 username #{username}不执行那么理论上SQL语句就会变成 SELECT * FROM user WHERE and age #{age}。但实际上WHERE标签会智能将 and 删除就会变成 SELECT * FROM user WHERE age #{age}。四. trim 标签trim 标签是一个单独的标签它可以单独使用如下图可以看到该标签一共提供了四个属性其中 prefix 翻译过来是前缀prefixOverrides 为 前缀重写suffix 为 后缀suffixOverrides 为 后缀重写。prtefix/suffix在trim标签中内容前面/后面添加指定内容prefixOverrides/suffixOverrides在trim标签中内容前面/后面去掉指定内容而且 trim 标签中有内容时trim就会生效如果没有内容trim标签也不会生效。我们想要达到上面 WHERE 标签一样的效果可以像下面这样写使用 prefix 属性添加前缀 WHERE使用 prefixOverrides 去掉多余的 and和or他们中间用 | 连接。select idfindByNameAndAge resultTypeUser select * from user trim prefixwhere prefixOverridesand|or if testusername ! null and username ! username #{username} /if if testage ! null and age ! and age #{age} /if /trim /select当我们if 标签内 and 写在后面的时候只需要使用 suffixOverrides 就可以达到效果如下代码所示select idfindByNameAndAge resultTypeUser select * from user trim prefixwhere suffixOverridesand|or if testusername ! null and username ! username #{username} and /if if testage ! null and age ! age #{age} /if /trim /select我们只需要将 prefixOverrides 改为 suffixOverrides就可以达到效果。五. choosewhenotherwise这三个标签一般情况下会一起出现它与我们Java中 if...else if...else 的功能非常相似。使用方式如下这里要注意when标签至少需要写一个而othersise最多只能写一个。choose when test判断条件.../when when test判断条件.../when otherwise判断条件/otherwise /choose当我们写这样的一个标签体时只要有一个条件成立它就不会再继续向下判断了直接将满足条件的字段拼接到SQL语句中。也就是说该标签体内就算有多个条件都满足但还是只会执行第一个满足条件的字段查询。它们也可以搭配WHERE/WHERE 或者trim/trim 使用大家可以自由选择这里我举例使用WHERE/WHERE示例代码举例如下select idfindByNameAndAge resultTypeUser select * from user where choose when testusername null and username ! username #{username} /when when testage ! null and age ! age #{age} /when otherwiseuid 1/otherwise /choose /where /select当我们像上面这样写的时候username 和 age 的判断只会执行一个即使用户填写的都是有效数据我们也会只执行第一个 username 的判断所以在开发时需要根据具体的业务场来使用该标签体。如果都不满足我们可以在 otherwise 中编写一个候选查询条件。六. foreachforeach 听名字我们也大概可以猜到它是用来循环的使用该标签可以实现我们对数据的批量添加和批量删除操作。foreach标签也为我们提供了几个属性下面我会依次说明这些属性是做什么用的cllection代表要遍历的数组Java接口在定义是最好使用Parm进行标注item表示数组中的每个元素open表示该标签体以什么开头close 表示该标签体以什么结尾separator表示数据之间的分隔符是什么现在有一个场景根据传输过来的数组中的用户id批量删除这些用户信息。就此场景我们就可以使用foreach标签来完成代码如下delete iddeleteListsByUid delete from user where uid in foreach collectionuserList itemuid open( close) separator, #{uid} /foreach /delete我们批量数据操作时前面有数据库关键字 in 所以需要加()因此则是以 ( 开头以 ) 结尾所以标签属性 open (close )。其实 open 和 close也不常用我们可以自己添加这里只是给各位说明它们两个的作用。此外因为数组中有多个数据因此每个数据在SQL语句中需要使用逗号隔开因此 separator 。