Mybatis学习笔记(五):动态SQL

  • Post author:
  • Post category:其他




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



版权声明:本文为qq_44769557原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。