什麼是動態SQL?
根據不同的條件生成不同的SQL語句
動態 SQL 是 MyBatis 的強大特性之一。如果你使用過 JDBC 或其它類似的框架,你應該能理解根據不同條件拼接 SQL 語句有多痛苦,例如拼接時要確保不能忘記添加必要的空格,還要注意去掉列表最後一個列名的逗號。利用動態 SQL,可以徹底擺脫這種痛苦。
以下測試實現一些常用的動態SQL
在接口中定義一些方法
package com.robot.mapper;
import com.robot.pojo.Blog;
import java.util.List;
import java.util.Map;
public interface BlogMapper {
int addBlog(Blog blog);
List<Blog> queryBlog(Map map);
List<Blog> queryBlog2(Map map);
List<Blog> queryBlog3(Map map);
int updateBlog(Map map);
List<Blog> queryBlogForeach(Map map);
}
在xml中實現
動態SQL這些標籤和Java、SQL中的關鍵字意思是差不多的
比如
-
if 標籤就是條件判斷語句;
-
where 標籤就是SQL中的where,只不過這個where標籤會自動去除或添加標籤內多餘的and
-
choose 標籤就是Java中的switch
-
下面代碼中的SQL片段,就相當於寫了一個方法,增加代碼的複用性,而使用這個方法的時候,就可以用include標籤來引用
-
foreach 標籤是遍歷查詢,如果根據id查詢,則需要有一個id集合:collection=“ids”
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.robot.mapper.BlogMapper">
<!-- 插入數據-->
<insert id="addBlog" parameterType="blog">
insert into blog (id, title, author, create_time, views) values (#{id},#{title},#{author},#{createTime},#{views})
</insert>
<!-- 如果不指定,則查詢所有,如果指定參數,則按條件查詢-->
<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語句+if, 防止where後直接拼接and-->
<select id="queryBlog2" 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>
<!-- choose-when-otherwise 相當於 Switch-case-default 語句,只會按順序選擇其中一個執行-->
<select id="queryBlog3" 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>
<!-- SQL片段,代碼複用,相當於封裝成一個方法-->
<sql id="if-blog">
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author}
</if>
</sql>
<!-- set標籤:動態前置set,刪掉無關逗號-->
<update id="updateBlog" parameterType="map">
update blog
<set>
<include refid="if-blog"></include>
</set>
where id = #{id}
</update>
<!-- 遍歷查詢 select * from blog where (id=? or id=? or id=?)-->
<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>
</mapper>
測試
以下測試,分別測試了以上所有實現的方法
package com.robot.mapper;
import com.robot.pojo.Blog;
import com.robot.utils.IDutils;
import com.robot.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.*;
public class MyTest {
@Test
public void addInitBlog() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(IDutils.getID());
blog.setTitle("Mybatis如此簡單");
blog.setAuthor("robot");
blog.setCreateTime(new Date());
blog.setViews(9999);
mapper.addBlog(blog);
blog.setId(IDutils.getID());
blog.setTitle("Java如此簡單");
mapper.addBlog(blog);
blog.setId(IDutils.getID());
blog.setTitle("Spring如此簡單");
mapper.addBlog(blog);
blog.setId(IDutils.getID());
blog.setTitle("微服務如此簡單");
mapper.addBlog(blog);
sqlSession.close();
}
@Test
public void queryBlog() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Map map = new HashMap();
// map.put("title", "Java如此簡單");
map.put("author", "robot");
List<Blog> blogs = blogMapper.queryBlog(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
@Test
public void queryBlog2() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Map map = new HashMap();
map.put("title", "Java如此簡單");
map.put("author", "robot");
List<Blog> blogs = blogMapper.queryBlog2(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
@Test
public void queryBlog3() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Map map = new HashMap();
map.put("title", "Java如此簡單");
map.put("views", "9999");
List<Blog> blogs = blogMapper.queryBlog3(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
@Test
public void updateBlog() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Map map = new HashMap();
map.put("id", "6d6cb532858b4fb1b0204ce5b8601c9f");
map.put("title", "Java攻城獅-robot");
//map.put("author", "baby");
int blog = blogMapper.updateBlog(map);
System.out.println(blog);
sqlSession.close();
}
@Test
public void queryBlogForeach() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
ArrayList<String> ids = new ArrayList();
ids.add("6d6cb532858b4fb1b0204ce5b8601c9f");
map.put("ids", ids);
mapper.queryBlogForeach(map);
sqlSession.close();
}
}
根據不同條件去拼接SQL語句,確實是一件很痛苦的事情,而使用動態SQL,就可以很靈活的去拼接這些SQL語句,徹底擺脫這種痛苦了。