17.Mybatis动态sql环境搭建及常用标签
1.什么是动态sql?
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
2.环境搭建
2.1 在mybatis数据库创建blog表
CREATE TABLE `blog` (
`id` varchar(50) NOT NULL COMMENT '博客id',
`title` varchar(100) NOT NULL COMMENT '博客标题',
`author` varchar(30) NOT NULL COMMENT '博客作者',
`create_time` date NOT NULL COMMENT '创建时间',
`views` int(30) NOT NULL COMMENT '浏览量'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
2.2 com.my.po编写实体类Blog
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Blog {
private int id;
private String title;
private String author;
private Date createTime;
private int views;
}
2.3 com.my.dao编写接口BlogMapper
public interface BlogMapper {
// 插入数据
int addBlog(Blog blog);
}
2.4 com.my.dao编写接口BlogMapper.xml
<insert id="addBlog" parameterType="Blog">
insert into blog(id,title,author,create_time,views)
values (#{id},#{title},#{author},#{createTime},#{views})
</insert>
2.5 测试类编写测试方法
@Test
public void addBlog(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(IDutils.getId());
blog.setTitle("鲁班学java");
blog.setAuthor("小鲁班");
blog.setCreateTime(new Date());
blogMapper.addBlog(blog);
blog.setId(IDutils.getId());
blog.setTitle("妲己学java");
blog.setAuthor("妲己");
blog.setCreateTime(new Date());
blogMapper.addBlog(blog);
blog.setId(IDutils.getId());
blog.setTitle("李白学java");
blog.setAuthor("李白");
blog.setCreateTime(new Date());
blogMapper.addBlog(blog);
blog.setId(IDutils.getId());
blog.setTitle("孙尚香学java");
blog.setAuthor("孙尚香");
blog.setCreateTime(new Date());
sqlSession.close();
}
2.6 测试结果
3.动态sql之if语句
3.1 BlogMapper编写接口方法
// 查询博客
List<Blog> queryBlogIf(Map map);
3.2 BlogMapper.xml编写动态sql
<select id="queryBlogIf" 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>
3.3 测试类编写测试方法
@Test
public void queryBlogIf(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Map map = new HashMap();
map.put("author","小鲁班");
List<Blog> blogs = blogMapper.queryBlogIf(map);
for (Blog blog:blogs) {
System.out.println(blog);
}
sqlSession.close();
}
3.4 测试结果
4.动态sql常用标签
4.1 BlogMapper编写接口方法
List<Blog> queryBlogChoose(Map map);
4.2 BlogMapper.xml编写动态sql
<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>
4.3 测试类编写测试方法
@Test
Public void queryBlogIfChoose(){
SqlSession sqlSession=MybatisUtils.getSqlSession();
BlogMapper blogMapper=sqlSession.getMapper(BlogMapper.class);
HashMap map=new HashMap();
map.put("title","鲁班学java");
List<Blog> blogs=blogMapper.queryBlogChoose(map);
System.out.println(blogs);
sqlSession.close();
}
4.4 测试结果
5.动态sql之set
5.1 BlogMapper编写接口方法
//更新博客
Int updateBlog(Map map);
5.2 BlogMapper.xml编写动态sql
<update id="updateBlog" parameterType="map">
Update blog
<set>
<if test="title!=null">
title=#{title},
</if>
<if test="author!=null">
author=#{author}
</if>
</set>
Where id=#{id}
</update>
5.3 测试类编写测试方法
@Test
Public void updateBlog(){
SqlSession sqlSession=MybatisUtils.getSqlSession();
BlogMapper blogMapper=sqlSession.getMapper(BlogMapper.class);
HashMap map=new HashMap();
map.put("title","猪八戒学java");
map.put("author","猪八戒");
map.put("id","74f4408b6c634a019bd23825768082a5");
blogMapper.updateBlog(map);
sqlSession.close();
}
5.4 测试结果
set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。
6.动态sql之foreach
6.0把数据库id改为1-2-3
6.1 BlogMapper编写接口方法
//查询第1-2-3
List<Blog> queryBlogForeach(Mapmap);
6.2 BlogMapper.xml编写动态sql
<select id="queryBlogForeach" parameterType="map" resultType="blog">
select* from blog
<where>
<foreach collection="ids"
item="id"
open="and("
close=")"
separator="or">
id=#{id}
</foreach>
</where>
6.3 测试类编写测试方法
@Test
Public void queryBlogForeach(){
SqlSession sqlSession=MybatisUtils.getSqlSession();
BlogMapper blogMapper=sqlSession.getMapper(BlogMapper.class);
HashMap map=new HashMap();
ArrayList<Integer> ids=new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(3);
map.put("ids",ids);
List<Blog> blogs=blogMapper.queryBlogForeach(map);
for(Blogblog:blogs){
System.out.println(blog);
}
sqlSession.close();
}
6.4 测试结果
6.5 总结
foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!
提示 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。