一、动态SQL
动态SQL:根据用户输入的不同查询条件,生成的不同SQL语句,之前咱们用的静态SQL,需要查询的条件几乎都是给定的,动态SQL语句功能是mybatis强大特性之一,当然JDBC也可以完成类似功能,只不过需要进行大量的SQL语句的拼接,会非常的麻烦。
虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。
动态SQL的本质:其实就是在原来的SQL语句的基础上增加的一些逻辑而已。
二、环境搭建
1、创建基础工程和数据库
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
2、工具类
public class IdUtils {
public static String getId(){
return UUID.randomUUID().toString().replaceAll("-", "");
}
}
3、实体类
@Data
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;
private int views;
}
4、Mapper接口和xml文件
public interface BlogMapper {
//查询博客
List<Blog> queryBlogIf(Map map);
}
//xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jason.dao.BlogMapper">
</mapper>
5、核心配置文件
<!--标准日志输出配置-->
<settings>
<!--标准日志工厂的实现-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--开启驼峰命名转换-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<mappers>
<mapper class="com.jason.dao.BlogMapper"/>
</mappers>
三、动态SQL详情:if+where
需求:根据作者名字和博客名字来查询博客!如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询
1、不使用动态SQL写法:由于该select语句用and连接,只要title和author中有一个为空,那么整个查询结果就是空。显然不是我们想要的结果
<select id="queryBlogIf" parameterType="map" resultType="Blog">
select * from mybatis.blog title = #{title} and author = #{author}
</select>
2、使用if进行判断:
如果author为空,则select * from mybatis.blog title = #{title},但是title为空呢?则select * from mybatis.blog and author = #{author},这个显然是一个错误的SQL语句,当然这也不是我们想要的结果。
<select id="queryBlogIf" parameterType="map" resultType="Blog">
select * from mybatis.blog
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</select>
3、动态SQL语句:
if+where语句,关键点在于where标签他可以去掉and。author为空则select * from mybatis.blog title = #{title};如果title为空则select * from mybatis.blog author = #{author},这样显然符合我们的要求。
<select id="queryBlogIf" parameterType="map" resultType="Blog">
select * from mybatis.blog
<where>
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
4、他的强大不仅仅如此,如果我们在条件中既需要title又需要author,这是他会只能的将我的and添加上。
select * from mybatis.blog title = #{title} and author = #{author};当然如果我们两个条件都不要,他会只能的帮助我将where条件都去掉。
<select id="queryBlogIf" parameterType="map" resultType="Blog">
select * from mybatis.blog
<where>
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
四、动态SQL详情:choose(where,when,otherwise)
我们不是在任何时候都要查询所有的条件,很多时候我们只想查任意一个条件,使用choose标签可以完成该任务,跟switch类似。具体:当三个条件都满足的时候,他也只会走第一个when分支;当第一个条件不满足,他会选择走第二个when分支;如果前面连个条件都不满足,他会选择走otherwise分支。这就是mybatis动态SQL的强大。
<select id="queryBlogChoose" parameterType="map" resultType="Blog">
select * from mybatis.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详情:set+if语句
这里主要针对的是更新语句问题,我们需要使用set语句进行处理
<update id="updateBlog" parameterType="Blog">
update mybatis.blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author}
</if>
</set>
where id = #{id}
</update>
六、SQL片段:
其实就是将出现频率很高的代码,提取出来,简化代码,在使用的时候直接进行调用就可以。
<!--SQL片段-->
<sql id="if-title-author">
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>
<select id="queryBlogIf" parameterType="map" resultType="Blog">
select * from mybatis.blog
<where>
<!--导入SQL片段id即可-->
<include refid="if-title-author"></include>
</where>
</select>
七、动态SQL详情:trim的使用
trim其实就是一个格式化标记,可以完成set或where标记的功能,他可以去掉and、or、,等,下面实例中使用where和trim是一样的效果。
<select id="queryBlogIf" parameterType="map" resultType="Blog">
select * from mybatis.blog
<!--<where>
<include refid="if-title-author"></include>
</where>-->
<trim prefix="where" prefixOverrides="and | or">
<include refid="if-title-author"></include>
</trim>
</select>
八、动态SQL详情:foreach的使用
Mapper.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 queryBlogForeach(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap hashMap = new HashMap();
ArrayList<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
ids.add(3);
hashMap.put("ids", ids);
List<Blog> blogs = mapper.queryBlogForeach(hashMap);
System.out.println(blogs);
sqlSession.close();
}