什么是动态SQL
动态SQL就是根据不同的条件生成不同的SQL语句,按照sql的格式,进行不同的拼接
建议:先在mysql中写出完整sql语句,然后在java中进行拼接
if
choose(when,otherwise)
trim(where,set)
foreach
搭建环境
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
创建基础工程
1.导包
2.编写配置文件
3.编写实体类
@Data
public class Blog {
private String author;
private Date createTime;//属性名和字段不一致,数据库中是create_time
private String id;
private String title;
private int views;
}
核心配置文件mybatis-config下的settings:将字段更改为驼峰命名
< setting name=“mapUnderscoreToCamelCase” value=“true”/>
IF
Mapper接口
public interface BlogMapper {
List<Blog> queryBlogIF(Map map);
}
接口实例
<select id="queryBlogIF" parameterType="map" resultType="Blog">
select *from mybatis.blog
<where>
<if test="author != null">
author=#{author}
</if>
<if test="title != null">
and title=#{title}
</if>
</where>
</select>
总结:
where可以动态增删and或or
if只要满足条件就拼接sql语句
choose(when,otherwise)
Mapper接口
public interface BlogMapper {
List<Blog> queryBlogByChoose(Map map);
}
接口实例
<select id="queryBlogByChoose" resultType="Blog" parameterType="map">
select *from mybatis.blog
<where>
<choose>
<when test="title !=null">
title=#{title}
</when>
<when test="author">
and author=#{author}
</when>
<otherwise>
and views=#{views}
</otherwise>
</choose>
</where>
</select>
总结:
choose 相当于java中的switch/case,选择性的只拼接一个满足的语句,其中满足的优先级就是谁先写的就拼接哪个sql。
otherwise 就是必须要有默认拼接的sql语句,主要choose中有满足的,且优先级最高,就不走otherwise,走优先级最高的语句。
set
Mapper接口
public interface BlogMapper {
int updateBlogBySet(Map map);
}
接口实例
<update id="updateBlogBySet" parameterType="map">
update mybatis.blog
<set>
<if test="title!=null">
title=#{title},
</if>
<if test="author!=null">
author=#{author},
</if>
<if test="views!=null">
views=#{views}
</if>
</set>
<where>
<if test="id !=null">
id=#{id}
</if>
</where>
</update>
总结:
set 用于sql中的update语句,动态设置set语句和其中的逗号。
trim可以自定义。
SQL片段
有的时候,我可能会将一些功能的部分抽取出来,方便复用
Mapper接口
public interface BlogMapper {
List<Blog> queryBlogIF(Map map);
}
接口实例
//使用SQL标签抽取出公共的部分
<sql id="if-author-title">
<if test="author != null">
and author=#{author}
</if>
<if test="title != null">
and title=#{title}
</if>
</sql>
//在需要使用的地方使用include标签引用即可
<select id="queryBlogIF" parameterType="map" resultType="Blog">
select *from mybatis.blog
<where>
<include refid="if-author-title"/>
</where>
</select>
总结:不要有where标签,最好都是if判断。最好基于单表来定义SQL片段,不要太复杂,否则主sql语句不支持
foreach
Mapper接口
数据库字段
List<Blog> queryByForEach(Map map);
接口实例
<!--
select*from mybatis.blog where 1=1 and(id=1 or id=2 or id=3)
传map,map中可以存在一个集合
-->
<select id="queryByForEach" resultType="Blog" parameterType="map">
select *from mybatis.blog
<where>
<foreach collection="ids" item="id" open="and (" close=")" separator="or">
id=#{id}
</foreach>
</where>
</select>
测试
@Test
public void queryForeach(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap hashMap = new HashMap();
ArrayList ids = new ArrayList();
ids.add("0b8f334e9d584448b86042f4830fa0a2");
ids.add("713b3fd5b54a48e68d05e35f219b98a0");
ids.add("249e150d5e4045bc9918d767eeb6578c");
hashMap.put("ids",ids);
List<Blog> blogs = mapper.queryByForEach(hashMap);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
动态SQL的另外一个常用的操作需求是对一个集合进行遍历,通常是在构建IN条件语句的时候
collection:集合
item:遍历元素
index:下标
open:拼接开始的符号
separator:分隔符
close:拼接结束的符号