动态SQL:指根据不同条件生成不同SQL语句。本质还是SQL语句,知识可以在SQL层面,去执行一个逻辑代码。动态SQL就是在拼接SQL语句,只要保证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
- 创建基础工程,构建如下目录结构
- 编写和数据库对应的实体类
@Data
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;
private int views;
}
- 编写mybatis核心配置文件和Mapper基础语句,核心配置文件中注意开启驼峰命名
<setting name="mapUnderscoreToCamelCase" value="true"/>
<mappers>
<mapper class="com.Nana.dao.BlogMapper"/>
</mappers>
<?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">
- 编写工具类,目的是获得一个没有-的uuid
@SuppressWarnings("all")
public class IDutils {
public static String getId(){
return UUID.randomUUID().toString().replaceAll("-","");
}
}
- 编写接口和Mapper插入语句
void addBook(Blog blog);
<insert id="addBook" parameterType="Blog">
insert into blog (id,title,author,create_time,views)
values(#{id},#{title},#{author},#{createTime},#{views})
</insert>
- 向表中插入数据
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(IDutils.getId());
blog.setTitle("Mybatis");
blog.setAuthor("狂神说");
blog.setCreateTime(new Date());
blog.setViews(9999);
mapper.addBook(blog);
blog.setId(IDutils.getId());
blog.setTitle("Java");
mapper.addBook(blog);
blog.setId(IDutils.getId());
blog.setTitle("Spring");
mapper.addBook(blog);
blog.setId(IDutils.getId());
blog.setTitle("微服务");
mapper.addBook(blog);
sqlSession.close();
2、if语句
作用:进行if判断
接口及核心mapper语句:
List<Blog> queryBlogIF(Map<String, String> map);
<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、where语句
作用:只在子元素返回任何内容的情况下才插入 “WHERE” 子句,会去除子句开头的 “AND” 或 “OR”
接口及核心mapper语句:
List<Blog> queryBlogWHERE(Map<String, String> map);
<select id="queryBlogWHERE" parameterType="map" resultType="Blog">
select * from blog
<where>
<if test="title != null">
and title=#{title}
</if>
<if test="author!=null">
and author=#{author}
</if>
</where>
</select>
4、choose、when、otherwise语句
作用:类似于Java中的switch、case、default语句
接口及核心mapper语句:
List<Blog> queryBlogCHOOSE(Map<String, String> map);
<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>
5、set语句
作用:动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)
接口及核心mapper语句:
void updateBlog(Map<String, String> map);
<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>
6、sql字段
作用:将重复用到的sql字段抽象出来,便于复用
接口及核心mapper语句:
List<Blog> queryBlogSql(Map<String, String> map);
<sql id="if-title-author">
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>
<select id="queryBlogSql" parameterType="map" resultType="Blog">
select * from blog
<where>
<include refid="if-title-author"></include>
</where>
</select>
注意:
- 最好基于表单来定义SQL片段
- 为了更好的复用性不要存在where标签
7、foreach语句
作用:允许指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。也允许指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符
接口及核心mapper语句:
List<Blog> queryBlogFOREACH(Map<String, String> map);
<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>
</select>