开发人员通常根据需求手动拼接 SQL 语句,这是一个极其麻烦的工作,而 MyBatis 提供了对 SQL 语句动态组装的功能,恰能解决这一问题。

MyBatis 的动态 SQL 元素与 JSTL 或 XML 文本处理器相似,常用 等元素。

if


动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分,所以在 MyBatis 中 元素是最常用的元素,它类似于 Java 中的 if 语句。

示例:

  1. <!--使用 if 元素根据条件动态查询用户信息-->
  2. <select id="selectUserByIf" resultType="com.po.MyUser" parameterType="com.po.MyUser">
  3. select * from user where 1=1
  4. <if test="uname!=null and uname!=''">
  5. and uname like concat('%',#{uname},'%')
  6. </if >
  7. <if test="usex !=null and usex !=''">
  8. and usex=#{usex}
  9. </if >
  10. </select>

choose、when、otherwise

有些时候不想用到所有的条件语句,而只想从中择取一二,针对这种情况,MyBatis 提供了 元素,它有点像 Java 中的 switch 语句。

示例:

  1. <!--使用choose、when、otherwise元素根据条件动态查询用户信息-->
  2. <select id="selectUserByChoose" resultType="com.po.MyUser" parameterType= "com.po.MyUser">
  3. select * from user where 1=1
  4. <choose>
  5. <when test="uname!=null and uname!=''">
  6. and uname like concat('%',#{uname},'%')
  7. </when>
  8. <when test="usex!=null and usex!=''">
  9. and usex=#{usex}
  10. </when>
  11. <otherwise>
  12. and uid > 10
  13. </otherwise>
  14. </choose>
  15. </select>

trim、where、set

元素

元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是 prefix 和 suffix。

可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是 prefixOverrides 和 suffixOverrides。正因为 元素有这样的功能,所以也可以非常简单地利用 来代替 元素的功能。

示例

  1. <!--使用trim元素根据条件动态查询用户信息-->
  2. <select id="selectUserByTrim" resultType="com.po.MyUser"parameterType="com.po.MyUser">
  3. select * from user
  4. <trim prefix="where" prefixOverrides = "and | or">
  5. <if test="uname!=null and uname!=''">
  6. and uname like concat('%',#{uname},'%')
  7. </if>
  8. <if test="usex!=null and usex!=''">
  9. and usex=#{usex}
  10. </if>
  11. </trim>
  12. </select>

元素

元素的作用是会在写入 元素的地方输出一个 where 语句,另外一个好处是不需要考虑 元素里面的条件输出是什么样子的,MyBatis 将智能处理。如果所有的条件都不满足,那么 MyBatis 就会查出所有的记录,如果输出后是以 and 开头的,MyBatis 会把第一个 and 忽略。

当然如果是以 or 开头的,MyBatis 也会把它忽略;此外,在 元素中不需要考虑空格的问题,MyBatis 将智能加上。

示例

  1. <!--使用where元素根据条件动态查询用户信息-->
  2. <select id="selectUserByWhere" resultType="com.po.MyUser" parameterType="com.po.MyUser">
  3. select * from user
  4. <where>
  5. <if test="uname != null and uname ! = ''">
  6. and uname like concat('%',#{uname},'%')
  7. </if>
  8. <if test="usex != null and usex != '' ">
  9. and usex=#{usex}
  10. </if >
  11. </where>
  12. </select>

元素

在动态 update 语句中可以使用 元素动态更新列。

  1. <!--使用set元素动态修改一个用户-->
  2. <update id="updateUserBySet" parameterType="com.po.MyUser">
  3. update user
  4. <set>
  5. <if test="uname!=null">uname=#{uname}</if>
  6. <if test="usex!=null">usex=#{usex}</if>
  7. </set>
  8. where uid=#{uid}
  9. </update>

foreach

元素主要用在构建 in 条件中,它可以在 SQL 语句中迭代一个集合。

元素的属性主要有 item、index、collection、open、separator、close。

  • item 表示集合中每一个元素进行迭代时的别名。
  • index 指定一个名字,用于表示在迭代过程中每次迭代到的位置。
  • open 表示该语句以什么开始。
  • separator 表示在每次进行迭代之间以什么符号作为分隔符。
  • close 表示以什么结束。


在使用 元素时,最关键、最容易出错的是 collection 属性,该属性是必选的,但在不同情况下该属性的值是不一样的,主要有以下 3 种情况:

  • 如果传入的是单参数且参数类型是一个 List,collection 属性值为 list。
  • 如果传入的是单参数且参数类型是一个 array 数组,collection 的属性值为 array。
  • 如果传入的参数是多个,需要把它们封装成一个 Map,当然单参数也可以封装成 Map。Map 的 key 是参数名,collection 属性值是传入的 List 或 array 对象在自己封装的 Map 中的 key。


示例

  1. <!--使用foreach元素查询用户信息-->
  2. <select id="selectUserByForeach" resultType="com.po.MyUser" parameterType=
  3. "List">
  4. select * from user where uid in
  5. <· item="item" index="index" collection="list"
  6. open="(" separator="," close=")">
  7. # {item}
  8. </foreach>
  9. </select>

bind

在进行模糊查询时,如果使用“${}”拼接字符串,则无法防止 SQL 注入问题。如果使用字符串拼接函数或连接符号,但不同数据库的拼接函数或连接符号不同。

例如 MySQL 的 concat 函数、Oracle 的连接符号“||”,这样 SQL 映射文件就需要根据不同的数据库提供不同的实现,显然比较麻烦,且不利于代码的移植。幸运的是,MyBatis 提供了 元素来解决这一问题。

示例

  1. <!--使用bind元素进行模糊查询-->
  2. <select id="selectUserByBind" resultType="com.po.MyUser" parameterType= "com.po.MyUser">
  3. <!-- bind 中的 uname 是 com.po.MyUser 的属性名-->
  4. <bind name="paran_uname" value="'%' + uname + '%'"/>
  5. select * from user where uname like #{paran_uname}
  6. </select>