Mybatis学习笔记:动态SQL
Posted 我永远信仰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis学习笔记:动态SQL相关的知识,希望对你有一定的参考价值。
12、动态SQL
什么是动态SQL:动态SQL就是指根据不同的条件生成不同的SQL语句
动态 SQL 是 MyBatis 的强大特性之一。
动态 SQL,可以彻底摆脱不同条件拼接 SQL 语句这种痛苦。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
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
自己添加表的数据
创建一个基础工程
0.导入Lombok
1.导包
2.编写配置文件
3.编写实体类
@Data
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;
private int views;
}
4.编写实体类的接口
5.编写实体类接口对应的Mapper
IF
<select id="getBlogIf" parameterType="map" resultType="com.yong.pojo.Blog">
select * from blog
<where>
<if test="title != null">
and title = #{title}
</if>
<if test="author!=null">
and author = #{author}
</if>
</where>
</select>
提供了可选的查找文本功能。如果不传入 “title”,那么所有处于 “ACTIVE” 状态的 BLOG 都会返回;如果传入了 “title” 参数,那么就会对 “title” 一列进行模糊查找并返回对应的 BLOG 结果
choose(when,otherwise)
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。
针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
还是上面的例子,但是策略变为:传入了 “title” 就按 “title” 查找,传入了 “author” 就按 “author” 查找的情形,只会选择先传入的一个。
<select id="getBlogWhen" parameterType="map" resultType="com.yong.pojo.Blog">
select * from blog
<where>
<choose>
<when test="title!=null">
title = #{title}
</when>
<when test="author!=null">
and author=#{author}
</when>
<otherwise>
and views >500
</otherwise>
</choose>
</where>
</select>
trim (where, set)
使用where标签可以解决匹配条件不成立,以及处理and和or的问题。
在动态sql里使用where是不安全的,因为条件1可能不成立,会导致sql语句错误。
<select id="getBlogIf" parameterType="map" resultType="com.yong.pojo.Blog">
select * from blog where
<if test="title != null">
title = #{title}
</if>
<if test="author!=null">
and author = #{author}
</if>
</select>
应该使用where标签
<select id="getBlogIf" parameterType="map" resultType="com.yong.pojo.Blog">
select * from blog
<where>
<if test="title != null">
and title = #{title}
</if>
<if test="author!=null">
and author = #{author}
</if>
</where>
</select>
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
<update id="updateBlog" parameterType="map">
update blog
<set>
<if test="author!=null">author=#{author},</if>
<if test="views!=null">views=#{views},</if>
</set>
where title=#{title}
</update>
总结:所谓的动态SQL,本质还是SQL语句,只是我们在SQL层面,去执行一个逻辑代码
SQL片段
可以将一些功能的部分抽取出来,方便复用
1.使用SQL标签抽取公共部分
<sql id="if-title-author" >
<if test="title != null">
and title = #{title}
</if>
<if test="author!=null">
and author = #{author}
</if>
</sql>
2.在需要的地方使用include便签引用即可
<select id="getBlogIf" parameterType="map" resultType="com.yong.pojo.Blog">
select * from blog
<where>
<include refid="if-title-author"></include>
</where>
</select>
注意事项:
- 最好基于单表来定义SQL片段
- 不要存在where标签,或者set等这些优化标签
foreach
<select id="getBlogs" parameterType="map" resultType="com.yong.pojo.Blog">
select * from blog
<where>
<foreach collection="ids" item="id" open="and (" close=")" separator="or">
id=#{id}
</foreach>
</where>
</select>
//list:存放要查找的id
List<Integer> list=new ArrayList<Integer>();
list.add(1);
list.add(2);
//万能的map,这里将list放进去。
HashMap map = new HashMap();
map.put("ids", list);
List<Blog> blogs = mapper.getBlogs(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
动态SQL就是在拼接sql语句,我们只需要保证SQL的正确性,按照SQL的格式,去排列组合就可以了
建议:
- 先在mysql中写出完整的SQL语句
- 然后再去修改为mybatis
以上是关于Mybatis学习笔记:动态SQL的主要内容,如果未能解决你的问题,请参考以下文章