MyBatis 中的动态 SQL 的相关使用方法

news2024/11/24 22:55:33

   为什么会有动态SQL,把SQL写死不是比较方便吗?其实有很多的举例,这里我那一个常见的来说,像我们用户注册,会有必填字段和非必填字段,有些传来的参数不一样,那对应的SQL也不一样,因此,在这些的场景底下我们需要使用动态SQL来完成。

  这里动态SQL我是使用XML的办法进行说明,因为使用注解不方便,而且不好观察哪里有误。这里我会先从一些常用的标签的介绍来对动态SQL进行使用的讲解。

1.1 <if>标签

    <insert id="insertByCondition">
        insert into userinfo(
            <if test="username != null">
                username
            </if>
            <if test="password != null">
                ,password
            </if>
            <if test="age != null">
                ,age
            </if>
            <if test="gender != null">
                ,gender
            </if>
        ) values (
            <if test="username != null">
                #{username}
            </if>
            <if test="password != null">
                ,#{password}
            </if>
            <if test="age != null">
                ,#{age}
            </if>
            <if test="gender != null">
                ,#{gender}
            </if>
        )
    </insert>

 

  从上述代码可以简单看出来,<if> 标签是一个<if test = "xxxx">xxxx</if>的结构,然后另一个是运行后的结果,这里发现如果if里面都有值的话,可以完好的插入,但是它就一定没问题吗?下面一个图我就简单注释掉几个来,实验一下。

  从上图可以简单的看错来,它是一个BadSql因为我们注掉了username导致,多了一个逗号那怎么样才能避免上述情况呢?那就要引入新的注解。

1.2<trim> 标签

  这里我们先简单介绍一下<trim>标签里面几个常见的属性:
     1. prefix:表示整个语句块,以prefix的值作为前缀。

     2. suffix:表示整个语句块,以suffix的值作为后缀。

     3. prefixOverrides:表示整个语句块要去除掉前缀。

     4. suffixOverrides:表示整个语句块要去掉后缀。

<insert id="insertByCondition">
        insert into userinfo
        <trim prefix="(" suffix=")" prefixOverrides=",">
            <if test="username != null">
                username
            </if>
            <if test="password != null">
                ,password
            </if>
            <if test="gender != null">
                ,gender
            </if>
            <if test="age != null">
                ,age
            </if>
        </trim>
        values
        <trim prefix="(" suffix=")" prefixOverrides=",">
            <if test="username != null">
                #{username}
            </if>
            <if test="password != null">
                ,#{password}
            </if>
            <if test="gender != null">
                , #{gender}
            </if>
            <if test="age != null">
                ,#{age}
            </if>

        </trim>
    </insert>

  上述因为username是不能为空,因此我把注掉username改为注掉gender,可以发现在<if>标签里面的问题给解决了。

1.3  <where>标签

<select id="queryUserByCondition" resultType="com.jincheng.mybatisdemo.model.UserInfo">
        select * from userinfo
        <where>
            <if test="age != null">
                age = #{age}
            </if>
            <if test="gender != null">
                and gender = #{gender}
            </if>
            <if test="deleteFlag">
                and delete_flag = #{deleteFlag}
            </if>
        </where>
    </select>
    <select id="queryUserByCondition" resultType="com.jincheng.mybatisdemo.model.UserInfo">
        select * from userinfo
        <trim prefix="where" prefixOverrides="and">
            <if test="age != null">
                age = #{age}
            </if>
            <if test="gender != null">
                and gender = #{gender}
            </if>
            <if test="deleteFlag">
                and delete_flag = #{deleteFlag}
            </if>
        </trim>
    </select>

  通过上面可以发现第一个是使用<where>标签进行写的,而另一个是通过使用<trim>标签进行写的。可以简单比对一下<where>标签,生成where关键字,并且去除最前面的and 或者 or,如果where标签代码块,没有一个查询条件,会省略掉where关键字。也可以使用<trim prefix="where" prefixOverrides="and">替换,但是这种情况下,子元素没有内容时,where关键字也会保留。

1.4 <set>标签

<update id="updateByCondition">
        update userinfo
        <set>
            <if test="password != null">
                password = #{password},
            </if>
            <if test="age != null">
                age = #{age},
            </if>
            <if test="gender != null">
                gender = #{gender}
            </if>
        </set>
            where id = #{id}
    </update>

  这里<set>标签,生成set关键字,去掉整个代码块后面的逗号。如果使用<trim prefix="set" suffixOverrides=",">可以进行替换。

1.5 <foreach>标签

  简单来说一下<foreach>标签里面的属性:

      1. collection:绑定方法参数中的集合,如LIst,Set,Map或数组对象

      2. item:遍历是的每一个对象

      3. open:语句块开头的字符串

      4. close:语句块结束的字符串

      5. separator:每次遍历之间间隔的字符串。

一般用在批量删除中等等。

    <delete id="batchDelete">
        delete  from userinfo
        where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </delete>

1.6 <inlcude>标签

  这个标签用于在xml映射文件中配置的SQL,有时可能会存在很多重复的片段,此时就会在很多多余的代码。

  这里我们需要对重复的代码片段进行抽取,将其通过<sql>标签封装到一个SQL片段,然后通过<include>标签进行引用:

        1.<sql> : 定义可重用的SQL片段

        2. <include>:通过属性refid,指定包含的SQL片段。

    <sql id="selectAll">
        select * from userinfo
    </sql>

    <select id="select" resultType="com.jincheng.mybatisdemo.model.UserInfo">
        <include refid="selectAll"></include>
    </select>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1589803.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ctf.show】获得百分之百的快乐

1.打开靶场 2.根据页面代码&#xff0c;get请求值只能小于4位数&#xff0c;否则会回显hack&#xff01; 尝试后确实是这样的&#xff1a; 请求值小于4位数&#xff0c;页面无变化&#xff1a; 发送请求值ls查看内容 3.根据2返回的值&#xff0c;发送值为?1>nl 创建一个nl…

每日一练(力扣)

我的思路是暴力枚举: 情况1:相同&#xff0c;就让子串和原串同时后移继续比较 情况2:不相同&#xff0c;就只让原串后移 public int strStr(String haystack, String needle) {if (haystack.length() < needle.length()){return -1;}for (int i 0; i < h…

Java | Leetcode Java题解之第15题三数之和

题目&#xff1a; 题解&#xff1a; class Solution {public List<List<Integer>> threeSum(int[] nums) {int n nums.length;Arrays.sort(nums);List<List<Integer>> ans new ArrayList<List<Integer>>();// 枚举 afor (int first 0;…

Harmony鸿蒙南向外设驱动开发-Audio

Audio驱动概述 多媒体系统是物联网设备开发中不可缺少的一部分&#xff0c;Audio作为其中重要的一个模块&#xff0c;Audio驱动模型的构建显得尤为重要。 本文主要介绍基于HDF&#xff08;Hardware Driver Foundation&#xff09;驱动框架开发的Audio驱动&#xff0c;包括Aud…

2023年蓝桥杯——日期统计

目录 题目链接&#xff1a;1.日期统计 - 蓝桥云课 (lanqiao.cn) 题目描述 思路 代码思路 定义数据结构&#xff1a; 处理每一个月&#xff1a; 检查日期序列在num100中是否存在&#xff1a; 计数匹配的日期数&#xff1a; 输出结果&#xff1a; 代码实现 总结 题目链…

面试:线程和线程池

目录 目标 一、线程有哪些状态 1、新建态&#xff08;NEW&#xff09;&#xff1a; 2、可运行态&#xff08;RUNNABLE&#xff09;&#xff1a; 3、终结态&#xff08;TERMINATED&#xff09;&#xff1a; 4、阻塞态&#xff08;BLOCKED&#xff09;&#xff1a; 5、等待态…

kafka快速入门+应用

Kafka, 构建TB级异步消息系统 1.快速入门 1.1 阻塞队列 在生产线程 和 消费线程 之间起到了 &#xff0c; 缓冲作用&#xff0c;即避免CPU 资源被浪费掉 BlockingQueue 解决 线程通信 的问题阻塞方法 put 、 take生产者、消费者 模式 生产者&#xff1a;产生数据的线程…

使用Mac自带终端进行远程ssh连接Linux服务器

废话不多说&#xff0c;直接上图 好吧&#xff0c;我承认我是多此一举&#xff0c;脱裤子放pi了&#xff0c;其实只需要在终端输入一行命令就可以了&#xff08;呜呜&#xff5e;&#xff09; ssh rootip -p 22 需要注意的是&#xff0c;命令里的ip地址同样要替换成你自己的服…

云LIS系统源码,ASP.NET区域LIS系统源码,实验室信息系统

云LIS系统源码&#xff0c;ASP.NET区域LIS系统源码&#xff0c;实验室信息系统 LIS技术架构&#xff1a;ASP.NET CORE 3.1 MVC SQLserver Redis等 开发语言&#xff1a;C# 6.0、JavaScript 前端框架&#xff1a;JQuery、EasyUI、Bootstrap 后端框架&#xff1a;MVC、S…

阿里云服务器带宽价格全解析,附报价单

阿里云服务器公网带宽怎么收费&#xff1f;北京地域服务器按固定带宽计费一个月23元/M&#xff0c;按使用流量计费0.8元/GB&#xff0c;云服务器地域不同实际带宽价格也不同&#xff0c;阿里云服务器网aliyunfuwuqi.com分享不同带宽计费模式下带宽收费价格表&#xff1a; 公网…

十五届web模拟题整理

模拟赛一期 1.动态的Tab栏 请在 style.css 文件中补全代码。 当用户向下滚动的高度没有超过标题栏&#xff08;即 .heading 元素&#xff09;的高度时&#xff0c;保持 Tab 栏在其原有的位置。当滚动高度超过标题栏的高度时&#xff0c;固定显示 Tab 栏在网页顶部。 /* TODO…

03 SQL基础 -- 查询与运算符

一、SELECT 语句基础 1.1 从表中选取数据 SELECT 语句 从表中选取数据时需要使用SELECT语句,也就是只从表中选出(SELECT)必要数据的意思。通过SELECT语句查询并选取出必要数据的过程称为匹配查询或查询(query) 基本SELECT语句包含了SELECT和FROM两个子句(clause)。示…

PointNet++函数square_distance(src, dst):计算两组点之间的欧式距离(代码详解)

文章目录 一、计算两组点之间的欧式距离二、举例三、中间结果输出 一、计算两组点之间的欧式距离 def square_distance(src, dst):"""Calculate Euclid distance between each two points.src^T * dst xn * xm yn * ym zn * zm&#xff1b;sum(src^2, dim-1…

模块化组合优势凸显钡铼IOy系列轻松应对大规模工业自动化工程

模块化组合是钡铼IOy系列独立式I/O模块的一大优势&#xff0c;它为大规模工业自动化工程提供了灵活性、可扩展性和定制性&#xff0c;从而轻松应对不同规模和复杂度的工厂应用。以下是关于模块化组合优势的详细解析&#xff1a; 1. 灵活性和定制性 模块化设计使得钡铼IOy系列…

字节Coze实现多Agent模式,文内在线体验,实时给产品经理提需求

摘要&#xff1a; 多Agent模式是一种分布式计算范式&#xff0c;它通过将复杂任务分解为多个子任务&#xff0c;并由独立的智能体&#xff08;Agents&#xff09;并行处理&#xff0c;从而提高系统的处理能力和效率。这种模式在自然语言处理、机器学习和其他数据密集型应用中尤…

未来汽车硬件安全的需求(1)

目录 1.概述 2.EVITA 2.1 EVITA HSM 2.2 EVITA保护范围 3.市场变化对车载网络安全的影响 3.1 非侵入式攻击的风险 3.2 量子计算机的蛮力攻击 3.3 整车E/E架构的变化 3.4 网络安全标准和认证 3.5 汽车工业的网络安全措施 4.汽车安全控制器 4.1 TPM2.0 4.2 安全控…

【2024最新】微信公众号怎么开启留言功能

关注微信公众号&#xff1a;怒码少年&#xff0c;回复关键词【电子书】可以免费获取计算机相关电子书 本文首发于&#xff1a;原文阅读-wx公众号&#xff1a;怒码少年 大家好&#xff0c;我是小码。 微信公众号从18年开始&#xff0c;正式关闭了留言功能。自此以后新注册的公…

华为校园公开课走入上海交大,鸿蒙成为专业核心课程

4月12日&#xff0c;华为校园公开课在中国上海交通大学成功举办&#xff0c;吸引了来自计算机等相关专业的150余名学生参加。据了解&#xff0c;由吴帆、陈贵海、过敏意、吴晨涛、刘生钟等教授在中国上海交通大学面向计算机系本科生开设的《操作系统》课程&#xff0c;是该系学…

python中time库的time.time()函数的作用是什么?

python中time库的time.time()函数的作用是什么&#xff1f; 作用&#xff1a;Python time time() 返回当前时间的时间戳&#xff08;1970纪元后经过的浮点秒数&#xff09;。 time()方法语法&#xff1a;time.time() #!/usr/bin/python # Write Python 3 code in this onlin…

程序“猿”自动化脚本(一)

1.剪贴板管理器&#x1f4cb; 您是否曾经发现自己在处理多个文本片段时忘记了复制的内容&#xff1f;有没有想过有一个工具可以跟踪您一天内复制的所有内容&#xff1f; 该自动化脚本会监视您复制的所有内容&#xff0c;将每个复制的文本无缝存储在时尚的图形界面中&#xff0c…