11.动态SQL

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

  • if:这条语句提供了可选的查找文本功能。
//动态sql--if
List<Blog> getBlog(Map<String,Object> map);
<select id="getBlog" parameterType="map" resultType="Blog">
    <!--
        查询语句要求:
            1.没有条件的时候全查
            2.有title条件时,按照title查询
            3.有views条件时,按照views查询
    -->
    select * from Blog
    <where>
        <if test="title != null">
            title = "${title}"
        </if>
        <if test="views != null">
            and views = ${views}
        </if>
    </where>
</select>
@Test
public void  getBlog(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    Map<String, Object> map = new HashMap<>();
    //map.put("title","MyBatis如此简单!");
    map.put("views",9999);
    
    List<Blog> blogList = mapper.getBlog(map);
    for (Blog blog : blogList) {
    System.out.println(blog);
    }
        
    sqlSession.close();
}
  • choose (when, otherwise)

  相当于Java 中的 switch 语句

   从多个条件中选择一个使用

List<Blog> getBlogByChoose(Map<String,Object> map);
<select id="getBlogByChoose" parameterType="map" resultType="Blog">
    select * from blog
    <!--where-->
    <where>
        <!--
        choose...when...语句相当于switch
        只会执行满足条件的一个语句!!
        -->
        <choose>
            <when test="title!=null">
                title=#{title}
            </when>
            <when test="author!=null">
                and author=#{author}
            </when>
            <otherwise>
                and views=9999
            </otherwise>
        </choose>
    </where>
</select>
@Test
public void  getBlogByChoose(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    Map<String, Object> map = new HashMap<>();
    map.put("title","MyBatis如此简单!");
    //map.put("views",9999);
    List<Blog> blogList = mapper.getBlogByChoose(map);

    for (Blog blog : blogList) {
        System.out.println(blog);
    }

    sqlSession.close();
}

 

  • trim (where, set)

 trim 元素来定制 where 元素的功能.

  1.prefix 前缀增加的内容前缀增加的内容

  2.suffix 后缀增加的内容

  3.prefixOverrides 前缀需要覆盖的内容,一般是第一个判断条件前面的多余的结构,如:第一个判断条件前面多了 ‘and'

  4.suffixOverrides 后缀需要覆盖的内容,一般是最后一个数据的后面符号,如:set值的时候,最后一个值的后面多一个逗号‘,'

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>
<trim prefix="SET" suffixOverrides=",">
  ...
</trim>
  • set

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

int updateBlogBySet(Map<String,Object> map);
<update id="updateBlogBySet" parameterType="map">
    update blog
    <set>
        <if test="title != null">
            title = "${title}",
        </if>
        <if test="views != null">
            views = ${views},
        </if>
    </set>
    where id="${id}";
</update>
    @Test
    public void getBlogBySet(){

        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        Map<String, Object> map = new HashMap<>();

        map.put("title","java如此简单!");
//        map.put("views",66666);
        map.put("id","0ba388b223c54bbc8ab4a461cd9b1562");

        mapper.updateBlogBySet(map);

        sqlSession.close();

    }
  • foreach动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)

  collection :指定要遍历的集合名称

  item:指定要迭代的对象

  index:索引

  open:以什么符号开头

  separator:元素要用的分隔符

  close:以什么符号结尾

//动态sql----foreach
List<Blog> getBlogForEach(Map map);
<!--
    查询id是1或2或3的blog
    select * from blog where id in (1,2,3)
-->
<select id="getBlogForEach" parameterType="map" resultType="Blog">
    select * from blog
    <where>
        <foreach collection="ids" item="id" open="id in(" separator="," close=")">
            #{id}
        </foreach>
    </where>
</select>
@Test
public void getBlogForEach(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();

    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

    HashMap<String, Object> map = new HashMap<>();

    ArrayList<Integer> ids = new ArrayList<>();
    ids.add(1);
    ids.add(2);
    ids.add(3);
    
    map.put("ids",ids);

    mapper.getBlogForEach(map);

    sqlSession.close();
}
  • where

  where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

 比如如下代码:

select * from Blog
<where>
    <if test="title != null">
        title = "${title}"
    </if>
    <if test="views != null">
        and views = ${views}
    </if>
</where>

如果都不满足条件的话,where语句不会执行    select * from Blog

第一个条件满足时,where语句生效 select * from Blog where title=?

当第二个条件满足但是第一个条件不满足时,where语句生效,第二语句前面的and会自动去除 select * from Blog where views=?

当都满足时,select * from Blog where title=?and views=?

  • SQL片段

 提取sql代码,提高代码的复用

  1.使用sql标签提取sql公共部分的代码

  2.使用include引用即可

  注意事项:
    最好基于单表来定义SQL片段!
    不要存在where标签!

<!--sql片段-->
<sql id="SetTest">
    <if test="title != null">
        title = "${title}",
    </if>
    <if test="views != null">
        views = ${views},
    </if>
</sql>

<update id="updateBlogBySet" parameterType="map">
    update blog
    <set>
       <include refid="SetTest"/>
    </set>
    where id="${id}";
</update>

 

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

 

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


建议:先在
Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL实现通用

 

posted on   人无远虑必有近忧  阅读(36)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示