MYBATIS教程 – 动态SQL

动态SQL是MyBatis的一个强大特性。在编写sql语句时,尝尝需要根据不同条件拼接sql语句,动态sql帮助开发者非常轻松地实现各种条件下的sql拼接。

下面是MyBatis提供的基于OGNL的动态SQL表达式。

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

if 语句

动态SQL中一个常见做法是有条件包含where子句。

示例:

<select id = "getByName" parameterType = "User" resultType = "User">
   SELECT * FROM User        
   <if test = "name != null">
      WHERE name LIKE #{name}
   </if> 
</select>

此语句查询用户列表,如果提供了用户名称,则根据用户名(like 匹配)查询用户。

可以包含多个if条件,如下所示:

<select id = "getByName" parameterType = "User" resultType = "User">

   SELECT * FROM User        
   <if test = "name != null">
      WHERE name LIKE #{name}
   </if>

   <if test = "id != null">
      AND id = #{id}
   </if> 
</select>

choose, when, otherwise语句

MyBatis提供了一个<choose>标签,类似Java的switch语句,可以在多个选项中只选择一个生效。

下面的示例,如果name不为空,根据name查询用户,如为空,接着判断下一个条件:如果id不为空,根据id查询用户,如果都不满足进入otherwise分支。

<select id = "getByNameOrId" parameterType = "User" resultType = "User">
   SELECT * FROM User
   <choose>
      <when test = "name != null">
          WHERE name LIKE #{name}
      </when> 

      <when test = "id != null">
         WHERE id = #{id}
      </when>

      <otherwise>
         WHERE 1 
      </otherwise>

   </choose>

</select>

where, set 语句

看前面的例子:

<select id = "getByName" parameterType = "User" resultType = "User">

   SELECT * FROM User        
   <if test = "name != null">
      WHERE name LIKE #{name}
   </if>

   <if test = "id != null">
      AND id = #{id}
   </if> 
</select>

如果前一个条件不满足,后面条件满足,生成的sql语句是错的,如下所示:

SELECT * FROM User
AND id = xxx

mybatis的<where>标签可解决此类问题:

<select id = "getByName" parameterType = "User" resultType = "User">

   SELECT * FROM User
   <where>
       <if test = "name != null">
          name LIKE #{name}
       </if>

       <if test = "id != null">
          AND id = #{id}
       </if> 
   </where>
</select>

<where>标签只在标签内至少有一个条件成立时才插入where,另外,如果内容以AND或OR开头,mybatis会自动去掉AND与OR。

类似<where>,动态更新时可以使用<set><set>标签可以用于动态包含需要更新的列。

示例:

<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>

foreach语句

foreach的主要作用是遍历一个集合构建in条件。例如,有一个用户List,可以通过foreach遍历List获取所有用户id作为in条件。

foreach标签的属性主要有item,index,collection,open,separator,close。

  • item 表示遍历集合时的当前元素(如果集合是map,item是值)
  • index 表示遍历集合时的当前元素索引(如果集合是map,item是键)
  • open 表示该语句开始字符串
  • separator 表示语句中元素之间的分隔符
  • close 表示该语句结束字符串
  • collection 表示集合的类型,任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象传递给 foreach 作为集合参数
<select id = "selectUserIn" resultType = "User" parameterType="java.util.List">
   SELECT *
   FROM User
   WHERE id in

   <foreach item = "item" index = "index" collection = "list"
      open = "(" separator = "," close = ")">
      #{item}
   </foreach>

</select>

动态sql例子

UserMapper.xml

映射文件中添加如下代码:

    ...

    <select id="getByName" parameterType="User" resultMap="result">
        SELECT * FROM User

        <if test="name != null">
            WHERE name LIKE #{name}
        </if>

    </select>

    ...

App.Java

应用程序main类文件中添加如下代码:


... System.out.println("------------ 动态sql获取用户 -----------"); User user3 = new User("user3"); user3 = (User) session.selectOne("User.getByName", user3); System.out.println(user3.getId()); System.out.println(user3.getName()); System.out.println("动态sql获取用户成功"); ....

运行

输出:

------------ 动态sql获取用户 -----------
3
user3
动态sql获取用户成功

例子源码

mybatis-demo1



浙ICP备17015664号 浙公网安备 33011002012336号 联系我们 网站地图  
@2019 qikegu.com 版权所有,禁止转载