1. If 语句

需求:根据作者名字和博客名字来查询博客!如果作者名字为空,那么只根据博客名字查询,反之,则
根据作者名来查询

  1. <!--需求1:
  2. 根据作者名字和博客名字来查询博客!
  3. 如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询
  4. select * from blog where title = #{title} and author = #{author}
  5. -->
  6. <select id="queryBlogIf" parameterType="map" resultType="blog">
  7. select * from blog where
  8. <if test="title != null">
  9. title = #{title}
  10. </if>
  11. <if test="author != null">
  12. and author = #{author}
  13. </if>
  14. </select>

这样写我们可以看到,如果 author 等于 null,那么查询语句为 select from user where title=#{title}, 但是如果title为空呢?那么查询语句为 select from user where and author=#{author},这是错误的 SQL 语句,如何解决呢?请看下面的 where 语句!

2. Where语句

修改上面的SQL语句:

  1. <select id="queryBlogIf" parameterType="map" resultType="blog">
  2. select * from blog
  3. <where>
  4. <if test="title != null">
  5. title = #{title}
  6. </if>
  7. <if test="author != null">
  8. and author = #{author}
  9. </if>
  10. </where>
  11. </select>

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。

2.1 和 where 元素等价的自定义 trim 元素

  1. <trim prefix="WHERE" prefixOverrides="AND |OR ">
  2. ...
  3. </trim>

3. Set语句

同理,上面的对于查询 SQL 语句包含 where 关键字,如果在进行更新操作的时候,含有 set 关键词,
我们怎么处理呢?

  1. <!--注意set是用的逗号隔开-->
  2. <update id="updateBlog" parameterType="map">
  3. update blog
  4. <set>
  5. <if test="title != null">
  6. title = #{title},
  7. </if>
  8. <if test="author != null">
  9. author = #{author}
  10. </if>
  11. </set>
  12. where id = #{id};
  13. </update>

这个例子中,set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)

3.1 与 set 元素等价的自定义 trim 元素

  1. <trim prefix="SET" suffixOverrides=",">
  2. ...
  3. </trim>

4. Choose语句

有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose
标签可以解决此类问题,类似于 Java 的 switch 语句

  1. <select id="queryBlogChoose" parameterType="map" resultType="blog">
  2. select * from blog
  3. <where>
  4. <choose>
  5. <when test="title != null">
  6. title = #{title}
  7. </when>
  8. <when test="author != null">
  9. and author = #{author}
  10. </when>
  11. <otherwise>
  12. and views = #{views}
  13. </otherwise>
  14. </choose>
  15. </where>
  16. </select>

5. Foreach语句

将数据库中前三个数据的id修改为1,2,3;
需求:我们需要查询 blog 表中 id 分别为1,2,3的博客信息

  1. <select id="queryBlogForeach" parameterType="map" resultType="blog">
  2. select * from blog
  3. <where>
  4. <!--
  5. collection:指定输入对象中的集合属性
  6. item:每次遍历生成的对象
  7. open:开始遍历时的拼接字符串
  8. close:结束时拼接的字符串
  9. separator:遍历对象之间需要拼接的字符串
  10. select * from blog where 1=1 and (id=1 or id=2 or id=3)
  11. -->
  12. <foreach collection="ids" item="id" open="and (" close=")"
  13. separator="or">
  14. id=#{id}
  15. </foreach>
  16. </where>
  17. </select>

6. SQL片段

有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们需要将这些代码抽
取出来,然后使用时直接调用。
提取SQL片段:

  1. <sql id="if-title-author">
  2. <if test="title != null">
  3. title = #{title}
  4. </if>
  5. <if test="author != null">
  6. and author = #{author}
  7. </if>
  8. </sql>

引用SQL片段:

  1. <select id="queryBlogIf" parameterType="map" resultType="blog">
  2. select * from blog
  3. <where>
  4. <!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace-->
  5. <include refid="if-title-author"></include>
  6. <!-- 在这里还可以引用其他的 sql 片段 -->
  7. </where>
  8. </select>

注意:
1、最好基于 单表来定义 sql 片段,提高片段的可重用性
2、在 sql 片段中不要包括 where

7. Bind元素

bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。比如:

  1. <select id="selectBlogsLike" resultType="Blog">
  2. <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  3. SELECT * FROM BLOG
  4. WHERE title LIKE #{pattern}
  5. </select>