这条语句提供了可选的查找文本功能,如果不传入 "title”,那么所有处于 "ACTIVE” 状态的 BLOG 都会返回,如果传入了 "title” 参数,那么就会对 "title” 一列进行模糊查找并返回对应的 BLOG 结果(细心的读者可能会发现, "title” 的参数值需要包含查找掩码或通配符字符)
1 2 3 4 5 6 7 8
<selectid="findActiveBlogWithTitleLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <iftest="title != null"> AND title like #{title} </if> </select>
<selectid="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <iftest="title != null"> AND title like #{title} </if> <iftest="author != null and author.name != null"> AND author_name like #{author.name} </if> </select>
<selectid="findActiveBlogLike"resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <choose> <whentest="title != null"> AND title like #{title} </when> <whentest="author != null and author.name != null"> AND author_name like #{author.name} </when> <otherwise> AND featured = 1 </otherwise> </choose> </select>
trim, where, set
前面几个例子已经方便地解决了一个臭名昭著的动态 SQL 问题,现在回到之前的 "if” 示例,这次我们将 "state = ‘ACTIVE’” 设置成动态条件,看看会发生什么。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<selectid="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE <iftest="state != null"> state = #{state} </if> <iftest="title != null"> AND title like #{title} </if> <iftest="author != null and author.name != null"> AND author_name like #{author.name} </if> </select>
如果没有匹配的条件会怎么样?最终这条 SQL 会变成这样:
1 2
SELECT * FROM BLOG WHERE
这会导致查询失败,如果匹配的只是第二个条件又会怎样?这条 SQL 会是这样:
1 2 3
SELECT * FROM BLOG WHERE AND title like ‘someTitle’
<selectid="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG <where> <iftest="state != null"> state = #{state} </if> <iftest="title != null"> AND title like #{title} </if> <iftest="author != null and author.name != null"> AND author_name like #{author.name} </if> </where> </select>
where 元素只会在子元素返回任何内容的情况下才插入 "WHERE” 子句,而且,若子句的开头为 "AND” 或 "OR”, where元素也会将它们去除。
如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能,比如,和 where元素等价的自定义 trim 元素为:
这个例子中, set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)
来看看与 set 元素等价的自定义 trim 元素吧:
1 2 3
<trimprefix="SET"suffixOverrides=","> ... </trim>
注意,我们覆盖了后缀值设置,并且自定义了前缀值。
foreach
动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候),比如:
1 2 3 4 5 6 7 8 9
<selectid="selectPostIn"resultType="domain.blog.Post"> SELECT * FROM POST P WHERE ID in <foreachitem="item"index="index"collection="list" open="("separator=","close=")"> #{item} </foreach> </select>
<selectid="selectBlogsLike"resultType="Blog"> <bindname="pattern"value="'%' + _parameter.getTitle() + '%'" /> SELECT * FROM BLOG WHERE title LIKE #{pattern} </select>