1、什么是动态SQL
动态SQL是MyBatis的强大特性之一。如果你使用过JDBC或其它类似的框架,你应该能理解根据不同条件拼接SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。其实动态SQL就是根据不同的条件生成不同的SQL语句。
MyBatis动态SQL:https://mybatis.org/mybatis-3/zh/dynamic-sql.html
环境搭建
DROP TABLE IF EXISTS `blog`;
CREATE TABLE `blog` (
`id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '博客id',
`title` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '博客标题',
`author` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '博客作者',
`create_time` datetime NOT NULL COMMENT '创建时间',
`views` int(30) NOT NULL COMMENT '浏览量',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
INSERT INTO `blog` VALUES ('1', 'MyBatis如此简单', '狂神说', '2021-03-06 21:12:22', 1);
INSERT INTO `blog` VALUES ('2', 'Spring如此简单', '狂神说', '2021-03-06 21:13:27', 2);
INSERT INTO `blog` VALUES ('3', 'Java如此简单', '狂神说', '2021-03-06 21:13:27', 3);
INSERT INTO `blog` VALUES ('4', '微服务如此简单', '狂神说', '2021-07-15 10:23:56', 1000);
实体类
package domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Blog {
private String id;
private String title;
private String author;
private String createTime;
private int views;
}
BlogMapper接口
package mapper;
import domain.Blog;
import java.util.List;
import java.util.Map;
public interface BlogMapper {
public List<Blog> getBlog(Map<String,Object> map);//查询所有
public void update(Map<String,Object> map);//更新
}
BlogMapper.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="mapper.BlogMapper">
<select id="getBlog" resultType="domain.Blog" parameterType="map">
select * from blog
</select>
</mapper>
1.1、标签
<select id="getBlog" resultType="domain.Blog" parameterType="map">
select * from blog where 1=1
<if test="title!=null">
and title=#{test}
</if>
<if test="author!=null">
and author=#{author}
</if>
</select>
其实就是一个拼接SQL,如果title不为空,就把”and title=#{test}”拼接到select语句后面。
测试
public class junit {
@Test
public void one(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Map<String,Object> map=new HashMap<>();
map.put("title","Java如此简单");
List<Blog> blog = mapper.getBlog(map);
for (Blog blog1 : blog) {
System.out.println(blog1);
}
sqlSession.close();
}
}
1.2、标签
为了简化上面where 1 = 1的条件拼装,我们可以采用
<select id="getBlog" resultType="domain.Blog" parameterType="map">
select * from blog
<where>
<if test="title!=null">
and title=#{test}
</if>
<if test="author!=null">
and author=#{author}
</if>
</where>
</select>
1.3、标签
其实choose标签和Java里面的switch一样,自带一个break!
<select id="getBlog" resultType="domain.Blog" parameterType="map">
select * from blog
<where>
<choose>
<when test="title!=null">
and title=#{title}
</when>
<when test="author!=null">
and author=#{author}
</when>
<otherwise>
and views=#{views}
</otherwise>
</choose>
</where>
</select>
1.4、标签
set会自动前置SET关键字,同时也会删掉无关的逗号
<update id="update" parameterType="map">
update 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 id=#{id}
</update>
1.5、标签
有的时候,我们可能会将一些功能的部分抽取出来,方便使用,减少冗余。
<sql id="one">
<if test="title!=null">
title=#{title},
</if>
<if test="author!=null">
author=#{author},
</if>
<if test="views!=null">
views=#{views},
</if>
</sql>
- 在需要使用的地方使用
标签引用即可 <update id="update" parameterType="map"> update blog <set> <include refid="one"></include> </set> where id=#{id} </update>
1.6、标签
- collection:里面存放的是一个集合
- item:遍历时的每一个元素
- open:起始位置的拼接符
- separator:隔断符
- close:结束位置的拼接符
<select id="getBlogForeach" resultType="domain.Blog" parameterType="map">
select *from blog
<where>
<foreach collection="ids" item="id" open="and id in(" close=")" separator=",">
#{id}
</foreach>
</where>
</select>
@Test
public void one(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Map<String,Object> map=new HashMap<>();
ArrayList<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
map.put("ids",ids);
List<Blog> blog = mapper.getBlogForeach(map);
for (Blog blog1 : blog) {
System.out.println(blog1);
}
sqlSession.close();
}
2、总结
动态SQL的本质就是再拼接SQL,我们只要保证SQL的准确性,按照SQL的格式·,去排列组合就可以了。