Mybatis-动态SQL

什么是动态SQL?

动态SQL就是根据不同的条件生成不同的SQL语句

官网描述:
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。
动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。

-------------------------------

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

-------------------------------

  • tips
    Mybatis-动态SQL_第1张图片
    在这里插入图片描述
<setting name="mapUnderscoreToCamelCase" value="true"/>

Mybatis-动态SQL_第2张图片

1. 搭建环境

2. 插入数据

@Data
public class Blog {
     
    private String id;
    private String title;
    private String author;
    private Date createTime;
    private int views;
}

public interface BlogMapper {
     
    //插入数据
    int addBlog(Blog blog);
}
<insert id="addBlog" parameterType="blog">
        insert into blog 
        (id,title,author,create_time,views) 
        value 
        (#{id},#{title},#{author},#{createTime},#{views})
    insert>
@Test
    public void testes01(){
     
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Blog blog = new Blog();

        blog.setId(IDUtils.getId());
        blog.setTitle("Mybatis-01");
        blog.setAuthor("xx");
        blog.setCreateTime(new Date());
        blog.setViews(999);
        mapper.addBlog(blog);

        blog.setId(IDUtils.getId());
        blog.setTitle("Mybatis-02");
        blog.setAuthor("xx");
        blog.setCreateTime(new Date());
        blog.setViews(888);
        mapper.addBlog(blog);

        blog.setId(IDUtils.getId());
        blog.setTitle("Mybatis-03");
        blog.setAuthor("zz");
        blog.setCreateTime(new Date());
        blog.setViews(777);
        mapper.addBlog(blog);

        sqlSession.close();
    }

Mybatis-动态SQL_第3张图片

3. If

public interface BlogMapper {
     
    List<Blog> queryBlogIf(Map map);
}
  • 在没有学where标签前,可以这样拼接,where state = ‘ACTIVE’
<select id="queryBlogIf" parameterType="map" resultType="blog">
        select * from blog where state = ‘ACTIVE’
            <if test="title != null ">
                 title = #{title}
            if>
            <if test="author != null">
                and author = #{author}
            if>
    select>
  • 当map为空时
@Test
    public void test02(){
     
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        HashMap map = new HashMap();
        List<Blog> blogs = mapper.queryBlogIf(map);
        for (Blog blog : blogs) {
     
            System.out.println(blog);
        }
        sqlSession.close();
    }

Mybatis-动态SQL_第4张图片

  • 当map不为空时:map.put(“author”,“xx”);
    Mybatis-动态SQL_第5张图片

  • 当map不为空时:map.put(“title”,“Mybatis-02”);
    Mybatis-动态SQL_第6张图片

4. where

  • where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
<select id="queryBlogIf" parameterType="map" resultType="blog">
        select * from blog
        <where>
            <if test="title != null ">
                 title = #{title}
            if>
            <if test="author != null">
                and author = #{author}
            if>
        where>
    select>

5. choose (when, otherwise)

  • 有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
<select id="queryBlogChoose" resultType="blog" parameterType="map">
       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>
  • 可以用where来消除掉拼接SQL语句时and的影响
  • 但在choose语句中,始终只会选择其中一条语句,所以可以都不用加and

6. set

  • set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
<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>

7. trim

  • where 元素等价的自定义 trim 元素为:
<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
trim>
  • set 元素等价的自定义 trim 元素
<trim prefix="SET" suffixOverrides=",">
  ...
trim>
  • < trim prefix="" prefixOverrides="" suffix="" suffixOverrides="" >
  • 移除所有标签中语句前面 prefixOverrides 属性中指定的内容,并且在前面插入 prefix 属性中指定的内容
  • 移除所有标签中语句后面 suffixOverrides 属性中指定的内容,并且在后面插入 suffix 属性中指定的内容
  • 这四个属性可以任意搭配

所谓的动态SQL,本质还是SQL语句,只是我们可以在SQL层面,去执行一个逻辑代码

8. SQL片段

  • 对于多个sql语句的共有部分,提取出来用,用sql标签提取,include标签复用(代码的复用)
<sql id="if-title-author">
        <if test="title != null">
            title = #{title}
        if>
        <if test="author != null">
            and author = #{author}
        if>
    sql>
<select id="queryBlogIf" parameterType="map" resultType="blog">
        select * from blog
        <where>
        <include refid="if-title-author">include>
        where>
    select>

Mybatis-动态SQL_第7张图片

  • 个人总结注意:建议只有相同条件下的语句可以替换:比如都是where或者set包裹的语句,如果只是参数接收语句一样,当心语句之间存在的“and” 和 “,”问题:比如where包裹的语句前面要有“and”,set包裹的后面有“,”

9. Foreach

  • foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量
  • 也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符
  • 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach
  • 当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
List<Blog> queryBlogForeach(Map map);

<select id="queryBlogForeach" resultType="blog" parameterType="map">
        select * from blog
        <where>
        <foreach collection="ids" item="id" open=" (" close=")" separator="or">
            id = #{id}
        foreach>
        where>
    select>
@Test
    public void test05(){
     
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        HashMap map = new HashMap();
        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(1);
        integers.add(2);
        map.put("ids",integers);
        List<Blog> blogs = mapper.queryBlogForeach(map);
        for (Blog blog : blogs) {
     
            System.out.println(blog);
        }
        sqlSession.close();
    }

Mybatis-动态SQL_第8张图片

动态SQL就是在拼接SQL语句,我们只要保证SQL的格式,去排列组合就可以了

建议:

  • 现在Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL实现通用即可

你可能感兴趣的:(Mybatis学习)