动态SQL
声明:本文章属于学习笔记,根据狂神说的Mybatis编写
Mybatis在线文档:https://mybatis.org/mybatis-3/zh/index.html
一丶 动态SQL之if语句
首先我们要理解什么是动态的sql语句,假如我只按照摸个sql语句的固定格式,那么他就不是动态的。我们在固有的sql语句中根据不同的值得限定,所查询的不同的值,那么就可以称之为动态的。
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
数据库表:
接口的设计:
BlogMapper.xml文件的配置:
<select id="queryBlog" parameterType="map" resultType="blog">
select *from blog where 1=1
<if test="title!=null">
and title=#{title}
</if>
<if test="author!=null">
and author=#{author}
</if>
</select>
在这里我们看后面的where 1=1 其实就是为了确保可以必须查出来结果用的。if中的语句其实就是拼接语句。
测试类测试:
@Test
public void test2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap<Object, Object> map = new HashMap<>();
map.put("title","kdynb");
List<Blog> blogs = mapper.queryBlog(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
我们看这边:
map添加数据,其实这就是体现出了动态sql,我想在固定的语句中,想查询什么就查询什么。
二丶动态sql常用的标签:
1丶where
我们看这样的一段代码:
我们可以看见,与原来的相比,缺少了and与其连接,报出了错误:
其实这种情况是因为程序分不清楚sql语句中的查询and为第一个还是其他的,所以这种解决的方法就要用到where标签。
运行结果:
2丶choose标签
首先看这样的一段代码:
<select id="queryBlog" 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标签和otherwise标签其实就是ifelse,如果不执行when里的那么就执行otherwise里的sql语句,也就是说,when里的语句要是执行了,那么otherwise里的语句就不执行了。
测试类测试:
@Test
public void test2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap<Object, Object> map = new HashMap<>();
map.put("title","kdynb");
map.put("views",999);
List<Blog> blogs = mapper.queryBlog(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
运行结果:
去掉map.put(“title”,“kdynb”);之后
运行结果:
3丶set,trim标签
首先我们要知道,如果不用标签,sql的更新语句在BlogMapper.xml文件中要怎么写:update 表 set 字段。
那么用标签该怎么写呢?
<update id="updateBlog" parameterType="map" >
update mybatis.blog
<set>
<if test="title!=null">
title=#{title},
</if>
<if test="author!=null">
author=#{author}
</if>
</set>
where id=#{id}
</update>
大致的例子是这样的。
接口的定义:
测试类测试:
@Test
public void test2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap<Object, Object> map = new HashMap<>();
map.put("title","kdynb");
map.put("views",999);
mapper.updateBlog(map);
sqlSession.close();
}
set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。我们输出的时候sql语句是没有逗号的!
同样的我们也可以用trim来进行设置:
<trim prefix="SET" suffixOverrides=",">
...
</trim>
prefix=‘SET’ 进行设置来选择set标签。suffixOverrides属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。也就是说suffixOverrides去掉这个逗号。
三丶动态sql值Foreach:
foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!
接口:
BlogMapper.xml文件的配置:
<select id="queryBlogForeach" parameterType="map" resultType="blog">
select *from mybatis.blog
<where>
<foreach collection=" ids" item="id" open="and (" close=")" separator="or">
id=#{id}
</foreach>
</where>
</select>
测试类测试:
@Test
public void test3(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap<Object, Object> map = new HashMap<>();
ArrayList<Object> ids = new ArrayList<>();
map.put("ids" ,ids);
List<Blog> blogs = mapper.queryBlogForeach(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
我们可看见:
中的集合是对应到测试类中对象引用值为ids集合的。如果不加,那么是这个就是报错:集合不能为空。