Mybatis四:动态sql

发布时间:2023-09-14 12:30

一、动态sql

1、什么是动态sql:根据不同的条件生成不同的sql语句

2、if语句:这条语句提供了可选的查找文本功能;
\"Mybatis四:动态sql_第1张图片\"


    <select id=\"findBlogByMap\" parameterType=\"map\" resultType=\"blog\">
        select * from blog where 1=1
        <if test=\"title != null and title != \'\'\">
            and title = #{title}
        </if>
        <if test=\"author!= null and author!= \'\'\">
            and author = #{author}
        </if>
    </select>

    <select id=\"findBlogByBlog\" parameterType=\"blog\" resultType=\"blog\">
        select * from blog where 1=1
        <if test=\"title != null and title != \'\'\">
            and title like \"%\"#{title}\"%\"
        </if>
        <if test=\"author!= null and author!= \'\'\">
            and author like \"%\"#{author}\"%\"
        </if>
    </select>
@org.junit.Test
    public void findBlogByBlog(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Blog blog = new Blog();
        //blog.setTitle(\"神\");
        blog.setAuthor(\"神\");
        List<Blog> blogByMap = mapper.findBlogByBlog(blog);
        for (Blog blogs : blogByMap) {
            System.out.println(blogs);
        }
        sqlSession.close();
    }

3、常用的动态标签

where标签:

  • 用where关键词可以实现多条件模糊查询,这样就不用 1=1恒等式来拼接,只按第一个条件查询时,若后面子句的开头为 “AND” 或 “OR”,where 元素会将它们去除,确保条件成立。按多个条件查询,where 又会自动加上 and 或者 or;
 <select id=\"findBlogByBlog\" parameterType=\"blog\" resultType=\"blog\">
        select * from blog
        <where>
        <if test=\"title != null and title != \'\'\">
            and title like \"%\"#{title}\"%\"
        </if>
        <if test=\"author!= null and author!= \'\'\">
            and author like \"%\"#{author}\"%\"
        </if>
        </where>
    </select>

set标签

  • set元素会动态前置set关键字,同时也会删掉无关的逗号;
  • 记得每个if语句后要加逗号,没有加逗号不会给你自动加上后面的语句
 //更新
    int updateBlog(Map map);
 <update id=\"updateBlog\" parameterType=\"map\">
        update blog
        <set>
            <if test=\"title != null and title != \'\'\">
               title = #{title},
            </if>
            <if test=\"author != null and author != \'\'\">
                author = #{author}
            </if>
            where id = #{id}
        </set>
    </update>

trim(where 、set)标签:

如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能;和 where 元素等价的自定义 trim 元素为

  • ...
  • prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容。
  • 与 set 元素等价的自定义 trim 元素;
  • ... 覆盖了后缀值设置,并且自定义了前缀值

choose、when、otherise标签

  • 相当于switch 、case,而且自带break,只会查出一个结果,因为成立一个条件之后break,后面的不会再判断
  • //优先条件查询 List findBlogByMap2(Map map);
<select id=\"findBlogByMap2\" parameterType=\"map\" resultType=\"blog\">
        select * from blog
        <where>
         <choose>
             <when test=\"title != null and title != \'\'\">
                 title = #{title}
             </when>
             <when test=\"author != null and author != \'\'\">
               and  author = #{author}
             </when>
             <otherwise>
                 and views = #{views}
             </otherwise>
         </choose>
        </where>
    </select>
@org.junit.Test
    public void findBlogByMap2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Map map = new HashMap();
        map.put(\"title\", \"神\");
        map.put(\"author\", \"狂神说\");
        map.put(\"views\",9999);
        List<Blog> blogByMap = mapper.findBlogByMap2(map);
        for (Blog blog : blogByMap) {
            System.out.println(blog);
        }
        sqlSession.close();
    }

SQL片段: 将公共的部分抽取出来,方便公用

  • 使用sql标签抽取公共部分
  • 在需要使用的时候使用include标签引用即可;
  • 注意事项
  • 最好基于单表来定义sql片段(sql放一个表的几个字段就行,多张表联查就不会支持)
  • 不要包含where标签(where一般是根据子句、条件来查询的,where提进去无法实现复用)
 <sql id=\"youwant\">
         <if test=\"title != null and title != \'\'\">
             title = #{title},
         </if>
         <if test=\"author != null and author != \'\'\">
            and author = #{author}
         </if>
     </sql>
    <select id=\"findBlogByMap\" parameterType=\"map\" resultType=\"blog\">
        select * from blog
        <where>
          <include refid=\"youwant\"/>
        </where>
    </select>
    

Foreach标签对集合遍历

  • foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!
  • 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给
    foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者
    Map.Entry 对象的集合)时,index 是键,item 是值。
<select id=\"selectPostIn\" resultType=\"domain.blog.Post\">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach item=\"item\" index=\"index\" collection=\"list\"
      open=\"(\" separator=\",\" close=\")\">
        #{item}
  </foreach>
</select>

案例:

  //查询1,2,3号
    List<Blog> findBlogByForeach(Map map);
<!--我们现在传递一个万能的map,map中可以存在一个集合
    select * from blog where 1=1 and (id=1 or id=2 or id=3)
    collection:一个自定义的集合,名为ids
    item:遍历出来的每一项,名为id
    open = \" 开头字段 (\" close=\")\"
    seperator=\" 分隔字段\"

    -->
    <select id=\"findBlogByForeach\" parameterType=\"map\" resultType=\"blog\">
        select * from blog
        <where>
            <foreach collection=\"ids\" item=\"id\" open=\"and (\" close=\")\" separator=\"or\">
                id =#{id}
            </foreach>
        </where>
    </select>
 SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Map map = new HashMap();
        ArrayList<Integer> ids = new ArrayList<Integer>();
        ids.add(1);
        ids.add(2);
        map.put(\"ids\", ids);
        map.put(\"author\", \"狂神说1=1\");
        map.put(\"id\",\"27fe9302735f4b21ae1047d45784e578\");
        mapper.updateBlog(map);
        List<Blog> blogByMap = mapper.findBlogByForeach(map);
        for (Blog blog : blogByMap) {
            System.out.println(blog);
        }
        sqlSession.close();

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号