目录
搭建环境
if
choose、when、otherwise
trim、where、set
sql片段
foreach
动态 SQL 是指在不同的情况下,根据不同的条件生成不同的 SQL 语句
数据库
CREATE TABLE `blog`(
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客标题',
`author` VARCHAR(30) NOT NULL COMMENT '博客作者',
`create_time` DATETIME NOT NULL COMMENT '创作时间',
`views` INT(30) NOT NULL COMMENT '浏览量'
)ENGINE=INNODB DEFAULT CHARSET=utf8
实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;
private int views;
}
实体类对应 mapper 和 xml 文件
public interface BlogMapper {
}
UUID 工具类
public class IDUtils {
public static String getId(){
return UUID.randomUUID().toString().replaceAll("-","");
}
}
插入数据测试
@Test
public void test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
mapper.addBlog(new Blog(IDUtils.getId(), "MyBatis学习", "苏福唉", new Date(), 154));
mapper.addBlog(new Blog(IDUtils.getId(), "Spring学习", "苏福唉", new Date(), 632));
mapper.addBlog(new Blog(IDUtils.getId(), "SpringMVC学习", "苏福唉", new Date(), 148));
mapper.addBlog(new Blog(IDUtils.getId(), "SpringBoot学习", "苏福唉", new Date(), 248));
sqlSession.close();
}
实现下面功能:
如果传入 title ,则查询指定博客,如果传入 author ,则查询该作者的所有博客,如果什么都不传,则查询所有博客
我们可以使用 MyBatis 中的 if 来实现该功能
表格数据
接口:通过 map 来接收参数
//查询博客
List queryBlogIF(Map map);
sql 语句:在这里我们使用 if 来实现不同情况下,不同 sql 语句的拼接
测试
@Test
public void test1(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Map map = new HashMap();
// map.put("title", "SpringMVC学习");
// map.put("author", "苏福唉");
List blogs = mapper.queryBlogIF(map);
for (Blog blog :
blogs) {
System.out.println(blog);
}
sqlSession.close();
}
不传参数
传入 title
传入 author
传入 title 和 author,我们可以发现 sql 语句将两者都拼接上了
choose、when、otherwise 语句其实就可以理解为 switch、case、default 语句
用该语句来实现如果传入 title ,则查询指定博客,如果传入 author ,则查询该作者的所有博客,如果什么都不传,则查询浏览量为632的博客
sql 语句
测试语句和之前一样
不传参数
传入 title
传入 author
传入 title 和 author,我们可以发现 sql 语句只拼接了 title ,即靠前的 when 标签中的内容
where
在前面的案例中,为了满足对 where 的拼接我们使用了 1=1 的形式,但是这样显然是不好的,因此我们可以使用 where 标签来进行拼接
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
使用 where 来修改上面案例
sql 语句
set
set 语句和 where 的作用类似,用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列,set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
示例
接口
//更新博客
int updateBlog(Map map);
sql 语句
update blog
title = #{title},
author = #{author}
where id = #{id}
测试
@Test
public void test2(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Map map = new HashMap();
map.put("title", "SpringMVC");
map.put("author", "苏福哥");
map.put("id", "a37f63f48d384f069f062f5c688114e5");
int i = mapper.updateBlog(map);
System.out.println(i);
sqlSession.close();
}
trim
我们可以使用 trim 来实现 where 和 set 的功能
实现 where
实现 set
update blog
title = #{title},
author = #{author}
where id = #{id}
总的来说,动态 sql 本质上还是 sql 语句,只是我们可以在 sql 层面来执行一个逻辑代码
有的时候,我们会将 sql 中一些公共的部分提取出来方便复用,减少代码冗余。例如,在上面的案例中我们写了下面代码
我们可以考虑将其抽取出来,使用 sql 标签
title = #{title}
and author = #{author}
再引入该片段,使用 include 标签
同样可以实现对应功能
我们有如下信息
需要查询作者为苏福唉并且博客 id 为 2 3的博客信息
使用 sql 语句
select * from blog where author = '苏福唉' and (id = 2 or id = 3)
在 MyBatis 中我们就可以使用 foreach 来实现
collection:表示传入的集合名称
item:集合中每一个元素名称
open:以什么开始
close:以什么结尾
separator:分割符
测试:
@Test
public void test3(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
List ids = new ArrayList<>();
ids.add(2);
ids.add(3);
Map map = new HashMap();
map.put("ids",ids);
List blogs = mapper.queryBlogForeach(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
可以发现成功拼接出了 sql,得到正确结果