首页 > 数据库 >11.动态SQL

11.动态SQL

时间:2023-01-08 01:55:12浏览次数:33  
标签:11 map views title sqlSession SQL 动态 where

什么是动态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实现通用

 

标签:11,map,views,title,sqlSession,SQL,动态,where
From: https://www.cnblogs.com/zuok/p/17033992.html

相关文章

  • MYSQL在Linux的安装
    MYSQL在Linux的安装Centos7centos默认带有mariadb,与mysql冲突1、检测当前系统中是否安装MySQLrpm-qa|grepmysql2、卸载已经安装的冲突软件rpm-e--n......
  • 数据分析中的SQL如何解决业务问题
    本文来自知乎问答。提问:数据分析人员需要掌握sql到什么程度?请问做一名数据分析人员,在sql方面需要掌握到什么程度呢?会增删改查就可以了吗?还是说关于开发的内容也要会?不同......
  • 在Win11上恢复旧的右键菜单!
    https://www.abackup.com/easybackup-tutorials/windows-11-always-show-more-options-right-click-666.htmlhttps://zhuanlan.zhihu.com/p/537254971总结:还是得注册表......
  • 通知:PostgreSQL证书领取(初级)
    PCA7天训练营第13营、PCA7天训练营第14营、PCA7天训练营第15营、PCA7天训练营第16营证书已由工业和信息化部教育与考试中心进行制作。​ 该批次证书发放事宜通知如下:......
  • 算法刷题 Day 11 | 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰
    20.有效的括号讲完了栈实现队列,队列实现栈,接下来就是栈的经典应用了。大家先自己思考一下有哪些不匹配的场景,在看视频我讲的都有哪些场景,落实到代码其实就容易......
  • 牛客进阶题目11:非重叠的序列检测
    可以用状态机也可用移位寄存器注意题目给rst的命名不带n后缀,但其实还是下降沿触发`timescale1ns/1nsmodulesequence_test1( inputwireclk, inputwirerst,......
  • 基于Patroni的PostgreSQL高可用实践
    因环境有限,本文在一台机器上实现基于Patroni的PostgreSQL高可用服务测试。1、安装软件包[root@lee~]#yum-yinstallhttps://mirrors.tuna.tsinghua.edu.cn/postgresql/r......
  • P3527 [POI2011]MET-Meteors
    题目之前学完整体二分就一直准备做来着,结果一直到今天才做对,所以我还是太菜辣!整体二分说白了就是将多次二分放在一起一次处理,也并不是简简单单的查询第$K$大,所以有些题......
  • SQLAlchemy
    安装pipinstallsqlalchemy基本使用fromsqlalchemyimportcreate_engine,Column,Integer,Stringfromsqlalchemy.ext.declarativeimportdeclarative_basefro......
  • 代码随想录算法训练营第11天
    今日刷题3道:20.有效的括号,1047.删除字符串中的所有相邻重复项,150.逆波兰表达式求值● 20.有效的括号题目链接/文章讲解/视频讲解:https://programmercarl.com......