什么是动态SQL
个人理解:动态SQL就是根据用户输入的参数不同,从而生成不同的SQL语句。
在Mybatis中,动态SQL就是在select,insert等标签中嵌入了if,set,foreach等标签。
搭建环境
本文接下来所举的例子,都是基于Blog(博客类)来说明的:
首先创建一个博客类(省略了getter和setter方法)
public class Blog {
private String id;
private String title;
private String author;
private Date create_time;
private int views;
}
相关接口
public interface BlogMapper {
//插入博客
int addBlog(Blog blog);
//查询博客
List<Blog> queryBlogsIF(Map map);
//查询博客2
List<Blog> queryBlogChoose(Map map);
//更新博客
int updateBlog(Map map);
//查询Id为1-3号的博客
List<Blog> queryBlogForeach(Map map);
}
IF标签
<select id="queryBlogsIF" parameterType="map" resultType="Blog">
select * from blog
<where>
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
解释:where标签里嵌入if标签,if标签中的test属性用来判断数据库中的字段不为空,不为空则追加if标签里的SQL语句(有多个if时,记得在SQL语句开头加上and)
Choose(when otherwise)标签
这里跟Java语句中的switch case语句道理类似:
<select id="queryBlogChoose" parameterType="map" resultType="Blog">
select * from blog
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
and author = #{author}
</when>
<otherwise>
and views = #{views}
</otherwise>
</choose>
</where>
</select>
choose标签只会选择其中一条when标签中的语句执行,即满足test的第一个。
Set标签
当执行更新操作的动态SQL时,会用到set标签:
<update id="updateBlog" parameterType="map">
update blog
<set>
<!--if标签中的SQL语句中别忘记加逗号,最后一个if标签中可以不加逗号-->
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author}
</if>
</set>
where id = #{id}
</update>
【注】在if标签中的SQL语句别忘记加逗号(最后一个If标签的逗号可加可不加,Mybatis可以去掉多余的逗号)
Foreach标签
动态SQL的另外一个常用操作需求就是针对集合进行遍历,通常是构建IN条件语句的时候
<!--
select * from blog where 1=1 and (id=1 or id=2 or id=3)
我们传递一个万能的Map,里面可以存放一个Collection集合
其中open属性代表拼接的sql语句以什么开始,close则代表以什么结束
separator代表分隔符
-->
<select id="queryBlogForeach" parameterType="map" resultType="Blog">
select * from blog
<where>
<foreach collection="ids" item="id" open="(" separator="or" close=")">
id = #{id}
</foreach>
</where>
</select>
这个collection属性值为存放在map里面的集合的键名(Key)
item属性值表示从这个集合中遍历的每一项都取名为id
其中open属性代表拼接的sql语句以什么开始
close则代表以什么结束
separator代表分隔符
测试代码
@Test
public void test5(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Map map = new HashMap();
String[] ids = {"1","2","3"};
//这里的map的键为ids
map.put("ids",ids);
List<Blog> blogs = mapper.queryBlogForeach(map);
for(Blog blog:blogs){
System.out.println(blog);
}
sqlSession.close();
}
Trim标签
它是一款自定义标签,具体功能如下:
<select id="" >
select * from blog
<trim prefix="WHERE" prefixoverride="AND |OR">
<if test="name != null and name.length()>0"> AND name=#{name}</if>
<if test="author != null and author.length()>0"> AND author=#{author}</if>
</trim>
</select>
这里,prefix代表要定制的SQL语句的前缀是什么
prefixoverride="AND |OR"代表从前往后数,去掉第一个 AND 或 OR
update blog
<trim prefix="set" suffixoverride="," suffix=" where id = #{id} ">
<if test="name != null and name.length()>0"> name=#{name} , </if>
<if test="author != null and author.length()>0"> author=#{author} , </if>
</trim>
suffix代表定制的SQL语句后缀
suffixoverride = “,” 代表从后往前数,去掉第一个(也就是从前往后数的最后一个)逗号