关于‘ Mybatis中的动态SQL语句 ‘解析

news2025/1/9 1:30:54

1、什么是动态SQL

MyBatis中的动态SQL是一种可以根据不同条件生成不同SQL语句的技术。它允许我们在映射文件中编写灵活的SQL语句,以便根据参数的不同情况来动态生成SQL语句。这种灵活性使得我们能够根据应用程序的需求来构建动态的查询语句。

2、动态SQL的作用

动态SQL是根据不同条件和需求,动态生成SQL语句的一种技术。它的作用主要有以下几点:

  • 条件灵活:使用动态SQL可以根据不同的条件生成不同的SQL语句,使得查询、更新或删除数据时能够根据具体情况进行灵活的处理。

  • 查询优化:有时候在编写静态SQL语句时难以预料到查询条件的变化,而使用动态SQL可以根据运行时的条件动态调整查询语句,从而更好地适应实际情况,提高查询性能。

  • 动态表名和字段名:有时候需要根据不同的场景来操作不同的表或字段,这时候就可以利用动态SQL来动态构建表名和字段名,实现灵活性和扩展性。

  • 防止SQL注入:通过使用参数化查询或者绑定变量的方式来构建动态SQL,可以有效防止SQL注入攻击,提升系统的安全性。

3、动态SQL的常用标签

  • if
  • where
  • choose
  • foreach
  • set
  • trim

图片alt

4、if 标签:条件判断

<select id="getSuppliersAll" resultType="pojo.Supplier" parameterType="Map">
    select supCode,supName,supContact,supPhone,supFax,createdTime from t_supplier 
        where
        <if test="supCode!=null and supCode!=''">
                and supCode like #{supCode}
        </if>
        <if test="supName!=null and supName!=''">
                and supName like #{supName}
        </if>
</select>

而上面的语句中 where 关键后直接跟 and 关键字,这就是一条错误的SQL语句。这个就可以使用 where1=1或者where标签了。

<select id="getSuppliersAll" resultType="pojo.Supplier" parameterType="Map">
    select supCode,supName,supContact,supPhone,supFax,createdTime from t_supplier 
        where 1=1
        <if test="supCode!=null and supCode!=''">
                and supCode like #{supCode}
        </if>
        <if test="supName!=null and supName!=''">
                and supName like #{supName}
        </if>
</select>

使用where1=1可以执行成功

5、where

作用:

  • 替换where关键字
  • 会动态的去掉第一个条件前的 and
  • 如果所有的参数没有值则不加where关键字
<select id="getSuppliersAll" resultType="pojo.Supplier" parameterType="Map">
    select supCode,supName,supContact,supPhone,supFax,createdTime from t_supplier
    <where>
       <if test="supCode!=null and supCode!=''">
          and supCode like #{supCode}
       </if>
       <if test="supName!=null and supName!=''">
          and supName like #{supName}
       </if>
    </where>
</select>

使用wehre标签也可以实现。

注意:需要给每个条件前都加上 and 关键字。

6、choose

条件分支:

  • when:用于定义条件成立时执行的代码块。它包含一个 test 属性,用于指定该条件分支的判断条件

  • otherwise:用于定义默认的代码块,当所有的 条件都不成立时,将行 中定义的代码块

<select id="getSuppliersAll" resultType="pojo.Supplier">
   select supCode,supName,supContact,supPhone,supFax,createdTime from t_supplier
   <where>
       <choose>  <!--相当于Switch-->
           <when test="supCode!=null and supCode!=''">  <!--相当于case-->
                and supCode like #{supCode}
           </when>
           <when test="supName!=null and supName!=''">  <!--相当于case-->
                and supName like #{supName}
           </when>
       </choose>
   </where>
</select>

7、foreach

用来迭代任何可迭代的对象(如数组,集合)。

  • collection 属性:
    mybatis会将数组参数,封装为一个Map集合。
    默认:array = 数组
    使用@Param注解改变map集合的默认key的名称
  • item 属性:本次迭代获取到的元素。
  • separator 属性:集合项迭代之间的分隔符。 foreach 标签不会错误地添加多余的分隔符。也就是最后一次迭代不会加分隔符。
  • open 属性:该属性值是在拼接SQL语句之前拼接的语句,只会拼接一次
  • close 属性:该属性值是在拼接SQL语句拼接后拼接的语句,只会拼接一次
(1)实现批量新增(List集合)
  • 接口定义方法
    /**
     * 批量新增
     */
    int insertManySupplier(@Param("Supplier") List<Supplier> Supplier);
  • xml文件中编写SQL
    <!--批量新增-->
    <insert id="insertManySupplier">
        insert into t_supplier(supCode,supName) values
        <foreach collection="Supplier" item="supplier" separator=",">
            (#{supplier.supCode},#{supplier.supName})
        </foreach>
    </insert>
  • 测试类中调用方法
    /**
     * 批量新增
     */
    @Test
    public void insertManySupplier() throws Exception {
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = factory.openSession();
        List<Supplier> supplierList = new ArrayList<Supplier>();
        Supplier supplier = new Supplier();
        supplier.setSupCode("CD_9969");
        supplier.setSupName("小王");
        Supplier supplier1 = new Supplier();
        supplier1.setSupCode("CD_9970");
        supplier1.setSupName("小红");
        Supplier supplier2 = new Supplier();
        supplier2.setSupCode("CD_9971");
        supplier2.setSupName("小强");
        supplierList.add(supplier);
        supplierList.add(supplier1);
        supplierList.add(supplier2);
        int i = sqlSession.getMapper(supplierMapper.class).insertManySupplier(supplierList);
        System.out.println("新增了---->"+i);
        sqlSession.commit();
    }
(2)实现批量删除(数组)
  • 接口定义方法
    /**
     * 批量删除
     */
    int deleteManySupplier(@Param("ids") int [] ids);
  • xml文件中编写SQL
    <!--批量删除-->
    <delete id="deleteManySupplier">
        delete from t_supplier where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
  • 测试类中调用方法
    /**
     * 批量删除
     */
    @Test
    public void deleteManySupplier() throws Exception{
        int ids[]={25,26,27};
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = factory.openSession();
        int i = sqlSession.getMapper(supplierMapper.class).deleteManySupplier(ids);
        System.out.println("删除了---->"+i);
        sqlSession.commit();
    }

8、set

实现动态修改
如果用户在进行数据修改时,注意一 点,如果哪个输入框没有输入内容,我们是将表中数据对应字段值替换为空白还是保留字段之前的值?答案肯定是保留之前的数据。

接下来我们就具体实现

  • 接口定义方法
    /**
     * 动态修改
     */
    int UpdateManySupplier(Supplier Supplier);

上述方法参数 Supplier就是封装了需要修改的数据,而id肯定是有数据的,这也是和添加方法的区别。

  • xml文件中编写SQL
    <!--动态修改-->
    <update id="UpdateManySupplier">
        update t_supplier
        <set>
            <if test="supCode!=null and supCode!=''">
                supCode=#{supCode},
            </if>
            <if test="supName!=null and supName!=''">
                supName=#{supName},
            </if>
            <if test="supPhone!=null and supPhone!=''">
                supPhone=#{supPhone},
            </if>
        </set>
        where id=#{id}
    </update>

set 标签可以用于动态包含需要更新的列,忽略其它不更新的列。

    /**
     * 动态修改
     */
    @Test
    public void UpdateManySupplier() throws Exception{
        Supplier supplier = new Supplier();
        supplier.setSupCode("DQ_6989");
        supplier.setSupName("地球有限公司");
        supplier.setId(17);
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = factory.openSession();
        int i = sqlSession.getMapper(supplierMapper.class).UpdateManySupplier(supplier);
        System.out.println("修改了---"+i);
        sqlSession.commit();
    }

从结果中SQL语句可以看出,只修改了 supCode,supName字段值,因为我们给的数据中只给Supplier 实体对象的 supCode,supName属性设置值了。这就是 set 标签的作用。

9、trim

trim 标签允许你在模板引擎或XML处理器中对字符串进行修剪操作,包括去除空白字符、去除指定的前缀和后缀,以及根据条件进行修剪。它提供了一种方便和灵活的方式来处理和清理字符串数据。

  • 属性及作用

图片alt

  • 动态查询
    <!--动态查询-->
    <select id="getSuppliersAll" resultType="pojo.Supplier">
        select supCode,supName,supContact,supPhone,supFax,createdTime from t_supplier
        <trim prefix="where" prefixOverrides="and|or" suffix=" LIMIT #{index},#{pageSize}">
            <if test="supCode!=null and supCode!=''">
                and supCode like #{supCode}
            </if>
            <if test="supName!=null and supName!=''">
                and supName like #{supName}
            </if>
            <if test="supPhone!=null and supPhone!=''">
                and supPhone like #{supPhone}
            </if>
        </trim>
    </select>
  • 动态修改
     <update id="UpdateManySupplier">
        update t_supplier
        <trim prefix="set" suffixOverrides="," suffix="where id=#{id}">
            <if test="supCode!=null and supCode!=''">
                supCode=#{supCode},
            </if>
            <if test="supName!=null and supName!=''">
                supName=#{supName},
            </if>
            <if test="supPhone!=null and supPhone!=''">
                supPhone=#{supPhone},
            </if>
        </trim>
    </update>

需要注意的是,prefix 和 suffix 属性是可选的,可以根据需要选择性地添加前缀和后缀。而 prefixOverrides 和 suffixOverrides 属性则提供了更加灵活的方式来根据条件进行字符串修剪操作。

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

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

相关文章

如何在Github上快速下载代码

由于网络环境问题&#xff0c;有时候比较难从Github上下载代码&#xff0c;我归纳了以下三种从Github上下载代码的方法&#xff0c;如何选择使用&#xff0c;可根据你的实际情况&#xff1a; 目录 方法一&#xff1a;使用 “Download ZIP” 按钮 方法二&#xff1a;使用 Git…

使用AUTOSAR来开发汽车基础软件的优点

1、高质量。以前我们采用手写代码的方式&#xff0c;是几个工程师在战斗。现在我们采用平台&#xff0c;BSW代码都是供应商提供的&#xff0c;我们相当于后面还有一个团队陪着我们在战斗。 2、低成本。大家都说采用AUTOSAR平台好贵&#xff0c;但是从长远来看是值得的&#xff…

服务器感染了.pings勒索病毒,如何确保数据文件完整恢复?

导言&#xff1a; 随着科技的不断进步&#xff0c;网络犯罪也在不断演变。其中之一的.pings勒索病毒是一种危险的恶意软件&#xff0c;它能够加密用户的数据文件&#xff0c;并要求支付赎金以解密这些文件。在本文中&#xff0c;91数据恢复将介绍.pings勒索病毒&#xff0c;以…

回归预测 | Matlab基于SMA+WOA+SFO-LSSVM多输入单输出回归预测

回归预测 | Matlab基于SMAWOASFO-LSSVM多输入单输出回归预测 目录 回归预测 | Matlab基于SMAWOASFO-LSSVM多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 SMAWOASFO-LSSVM回归预测 基于黏菌算法鲸鱼算法向日葵算法优化LSSVM回归预测 其中包含三种改进…

常用机床类型的用途和介绍

随着市场对机加工需求的提升&#xff0c;机械加工的技术精度也随之提高&#xff0c;机床的种类也就越来越多。 根据加工方法和使用的工具进行分类&#xff0c;国家将机床编制为11类&#xff1a;车床、钻床、镗床、磨床、齿轮加工机床、螺纹加工机床、铣床、刨床、拔床、锯床等…

Frps服务端一键配置脚本搭建记录

安装&#xff0c;一般修改80&#xff0c;443端口&#xff0c;其他默认回车 Gitee wget https://gitee.com/mvscode/frps-onekey/raw/master/install-frps.sh -O ./install-frps.sh chmod 700 ./install-frps.sh ./install-frps.sh installGithub wget https://raw.githubuse…

2024美赛数学建模思路 - 复盘:光照强度计算的优化模型

文章目录 0 赛题思路1 问题要求2 假设约定3 符号约定4 建立模型5 模型求解6 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 问题要求 现在已知一个教室长为15米&#xff0c;宽为12米&…

5个不买后悔的云服务器推荐(2024年更新)

作为多年站长使市面上大多数的云厂商的云服务器都使用过&#xff0c;很多特价云服务器都是新用户专享的&#xff0c;本文有老用户特价云服务器&#xff0c;阿腾云atengyun.com有多个网站、小程序等&#xff0c;国内头部云厂商阿里云、腾讯云、华为云、UCloud、京东云都有用过&a…

Linxu每日智囊

每日分享三个Linux命令,悄悄培养读者的Linux技能。 欢迎关注公众号(NLP Research) apt 作用 包管理器 语法 apt [选项] 软件包 参数: -h:帮助-y:当安装过程提示选择全部为"yes"-q:不显示安装的过程案例 列出所有可更新的软件清单命令sudo apt update升级软…

完整的模型训练套路(一、二、三)

搭建神经网络 model import torch from torch import nn#搭建神经网络 class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.model nn.Sequential(nn.Conv2d(3, 32, 5, 1, 2),nn.MaxPool2d(2),nn.Conv2d(32, 32, 5, 1, 2),nn.MaxPool2d(2),nn.Conv…

统计学-R语言-2.1

文章目录 前言安装过程总结 前言 上篇文章介绍了统计学-R语言的介绍&#xff0c;本篇文章介绍如何安装R软件。 安装过程 可以登录官网&#xff0c;https://www.r-project.org/&#xff0c;点击此处跳转。 点进去下滑找到China,之后找任意一个链接地址进行下载即可。 我点的是…

QT 文本框的绘制与复选框组键

.cpp文件 #include "widget.h" #include "ui_widget.h"#include<QDebug> Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//更改窗口标题setWindowTitle("我爱xyy");//更改图标setWindow…

MySQL中order by是怎么工作的?

在如上图中所示的explain的执行结果中&#xff0c;Extra字段中的“Using filesort”表示的就是需要排序&#xff0c;MySQL会给每个线程分配一块内存用于排序&#xff0c;称为sort_buffer。 索引city如上图所示 上述语句的执行流程如下&#xff1a; 1、初始化sort_buffer&…

【AIGC-文本/图片生成视频系列-8】Align your Latents: 基于潜在扩散模型的高分辨率视频合成

目录 一. 项目概述与贡献 二. 方法详解 三. 应用总览 四. 个性化视频生成 五. 实时卷积合成 六. 更多结果 七. 论文 八. 个人思考 AI生成高分辨率视频一直是一个挑战。 今天讲解一篇潜在扩散模型&#xff08;LDM&#xff09;用于高分辨率、时间一致且多样化的视频生成…

JVM加载class文件的原理机制

1、JVM 简介 JVM 是我们Javaer 的最基本功底了&#xff0c;刚开始学Java 的时候&#xff0c;一般都是从“Hello World ”开始的&#xff0c;然后会写个复杂点class &#xff0c;然后再找一些开源框架&#xff0c;比如Spring &#xff0c;Hibernate 等等&#xff0c;再然后就开发…

leaflet学习笔记-带有方位角信息的圆的绘制(七)

前言 项目中有一个需求&#xff0c;就是需要绘制一个圆&#xff0c;并且绘制的时候还要设置方位角&#xff0c;最后返回圆的坐标集合和方位角。本功能使用Leaflet-GeomanTurf.jsleaflet实现。 方位角简介 在陆地导航中&#xff0c;方位角通常表示为 alpha、α&#xff0c;并定…

java中解码和编码出现乱码原因

一、UTF-8和GBK编码方式 如果采用的是UTF-8的编码方式&#xff0c;那么1个英文字母 占 1个字节&#xff0c;1个中文占3个字节如果采用GBK的编码方式&#xff0c;那么1个英文字母 占 1个字节&#xff0c;1个中文占2个字节 二、idea和eclipse的默认编码方式 其实idea和eclipse的…

力扣题解24. 两两交换链表中的节点(图解递归和双指针)

24. 两两交换链表中的节点 题目描述&#xff1a; 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&…

使用Pygame显示文字的示例代码

import pygame import syspygame.init()# 设置窗口尺寸 win_size (800, 600) screen pygame.display.set_mode(win_size) pygame.display.set_caption("文字显示示例")# 设置字体和文字内容 font pygame.font.SysFont(None, 48) # 使用系统默认字体&#xff0c;字…

第十一章 Cookie

第十一章 Cookie 1.什么是Cookie2.Cookie的创建3.Cookie的获取4.Cookie值的修改5.谷歌浏览器和火狐浏览器如何查看Cookie6.Cookie的存活设置7.Cookie的path属性8.Cookie练习之免用户名登入 1.什么是Cookie 2.Cookie的创建 下面我看看如何创建Cookie&#xff0c;如何让客户端保…