动态SQL:根据不同条件生成对应SQL语句
应用实例:可以根据不同条件进行搜索,可以实现SQL复用,比如根据年龄,性别搜索
IF标签
BlogMapper.java
//查询博客
List<Blog> queryBlog(Map map);
BlogMapper.xml
<select id="queryBlog" parameterType="map" resultType="blog">
select * from mybatis.blog where 1=1
<if test="title!=null">
and title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</select>
Test.java
@Test
public void queryBlogIF(){
SqlSession sqlSeession = MybatisUtils.getSqlSeession();
BlogMapper mapper = sqlSeession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("title","Java如此简单");
List<Blog> blogs = mapper.queryBlog(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSeession.close();
}
where标签
<select id="queryBlog" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<if test="title!=null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
SQL拼接时可能出现where and或where or这样的错误语句,使用where标签就可以去掉第一个判断条件前的and或or。
choose(when,otherwise)标签
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
and author = #{author}
</when>
<otherwise>
and views = #{views}
</otherwise>
</choose>
</where>
set标签
<update id="updatteBlog" parameterType="map">
update mybatis.blog
<set>
<if test="title!=null">
tittle = #{title},
</if>
<if test="auhor!=null">
author=#{author}
</if>
</set>
where id=#{id}
</update>
trim标签
if标签产生的问题
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
如果没有匹配的条件会怎么样?最终这条 SQL 会变成这样:
SELECT * FROM BLOG
WHERE
这会导致查询失败。如果匹配的只是第二个条件又会怎样?这条 SQL 会是这样:
SELECT * FROM BLOG
WHERE
AND title like ‘someTitle’
trim标签可以通过自定义 trim来定制标签功能
和 where 元素等价的自定义 trim 元素为:
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
和 set 元素等价的自定义 trim 元素为:
<trim prefix="SET" suffixOverrides=",">
...
</trim>
上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 或suffix属性中指定的内容。
SQL片段
将公共部分抽取出来,进行复用
1、使用SQL标签抽取公共部分
<sql id="if-title-author">
<if test="title!=null">
tittle = #{title},
</if>
<if test="auhor!=null">
author=#{author}
</if>
</sql>
2、在需要使用的地方使用include标签引用
<select id="queryBlogIF" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<include refid="if-title-author"></include>
</where>
</select>
注意事项:
- 最后基于单标来定义SQL片段
- 不要存在where标签
- 尽量只用if片段
foreach
select * from mybatis.blog where 1=1 and (id=1 or id=2 or id=3)
实现:
<select id="queryBlogIF" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<foreach collection="idCollection" item="id" open="(" close=")" separator="or">
#{id}
</foreach>
</where>
</select>