Mybatis中实现动态SQL

news2024/9/21 18:55:28

目录

  • 1 背景
  • 2 if判断
  • 2 choose(when,otherwise)选择分支进入
  • 3 where
  • 4 set
  • 5 trim
  • 6 foreach循环遍历
  • 7 小结


1 背景

在这里插入图片描述

不建议使用,但是有些需求又不得不用回来温习下。动态SQL语句,也就意味着SQL语句不在是一成不变的而是具有多样性.

2 if判断

if的用法还是跟平常差不多的(不过没有else if也没有else)

<update id="modify" parameterType="User">
        UPDATE `smbms_user`
        <trim prefix="set" suffixOverrides="," suffix="where id=#{id}">
            <if test="userCode!=null">`userCode` = #{userCode} , </if>
            <if test="userName!=null">`userName` = #{userName} , </if>
            <if test="userPassword!=null">`userPassword` = #{userPassword} , </if>
            <if test="gender!=null">`gender` = #{gender} , </if>
            <if test="birthday!=null">`birthday` = #{birthday} ,</if>
            <if test="phone!=null">`phone` = #{phone} , </if>
            <if test="address!=null">`address` = #{address} , </if>
            <if test="userRole!=null">`userRole` = #{userRole} , </if>
            <if test="createdBy!=null">`createdBy` = #{createdBy} , </if>
            <if test="creationDate!=null">`creationDate` = #{creationDate} , </if>
            <if test="modifyBy!=null">`modifyBy` = #{modifyBy}</if>
        </trim>
    </update> 

如上面的代码,如果是空的字段则不执行更新操作

2 choose(when,otherwise)选择分支进入

choose就相当于Java中的switch,when相当于case,otherwise相当于default

<select id="getBill" resultType="Bill">
        SELECT * FROM smbms_bill b JOIN smbms_provider p  ON b.providerId=p.id
        WHERE 1=1
        <choose>
            <!-- 条件为false则继续执行下面的when,反之亦然如此 -->
            <when test="id!=null">
                AND    b.providerId=#{id} 
            </when>
            <!-- 条件为true则不会执行otherwise,反之亦然如此 -->
            <when test="proName!=null">
                AND p.proName LIKE CONCAT('%',#{proName},'%')
            </when>
            <!-- 当都不满足时执行默认值 -->
            <otherwise>
                AND p.proContact LIKE CONCAT('%张%')
            </otherwise>
        </choose>
    </select>

3 where

此标签可以忽略条件中多余的and和or如下

SELECT * FROM smbms_bill b JOIN smbms_provider p  ON b.providerId=p.id
        <where>
            <if test="id!=null">
                 AND b.providerId=#{id}
            </if>
            <if test="proName!=null">
                 AND p.proName LIKE CONCAT('%',#{proName},'%')
            </if>
        </where>

假设id为1 proName为北京 两个if都满足条件时就会拼凑成这样

SELECT * FROM smbms_bill b JOIN smbms_provider p  ON b.providerId=p.id WHERE b.providerId=1 AND p.proName LIKE CONCAT('%北京%')

其实解决这种情况不用where也是可以的,只需在前面加上一个为真的条件即可

SELECT * FROM smbms_bill b JOIN smbms_provider p  ON b.providerId=p.id
        where 1=1
        <if test="id!=null">
             AND b.providerId=#{id}
        </if>
        <if test="proName!=null">
             AND p.proName LIKE CONCAT('%',#{proName},'%')
        </if>

效果也是一样的

4 set

此标签可以忽略多余的逗号

UPDATE `smbms_user` 
        <set>
            <if test="userPassword!=null">
                `userPassword` = #{userPassword},
            </if>
        </set>
           WHERE `id` = #{id} ;

5 trim

此标签属性如下

  1. prefix:通过自动识别是否有返回值,在trim包含的内容上加上前缀
  2. suffix:在trim包含的内容上加上后缀
  3. prefixoverrides:对trim包含内容的首部进行指定内容的忽略
  4. suffixoverrides;对于trim包含内容的尾部进行指定内容的忽略

栗子1

<!-- 添加内容前面加上 where 并且忽略 and或者or -->
        <trim prefix="where" prefixOverrides="and|or">
            <if test="userRole!=null">
                and userRole=#{userRole}
            </if> 
            <if test="userName!=null and userName!=''">
                and u.userName like CONCAT('%',#{userName},'%')
            </if>
            order by creationDate DESC limit #(from),#(pageSize)
        </trim>

栗子2

UPDATE `smbms_user`
        <!-- 在内容前加上 set 并且忽略内容最后的逗号 且在内容后面加上查询条件  -->
        <trim prefix="set" suffixOverrides="," suffix="where id=#{id}">
            <if test="userCode!=null">`userCode` = #{userCode} , </if>
            <if test="userName!=null">`userName` = #{userName} , </if>
        </trim>

6 foreach循环遍历

此标签的属性如下

  1. item表示集合中每一个元素进行迭代时的别名
  2. index:指定一个名字,用于表示每次迭代的位置.好比for循环中自定义的 i
  3. open表示该语句以什么开始,在in条件语句中以"("开始
  4. separator表示在每次进行迭代之间以什么符号作为分隔 符,在in条件语句中以逗号进行分隔
  5. close表示以什么结束。在in条件语句中以")"结尾
  6. 在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,主要有以下3种情况:
    1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
    2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
    3. 如果传入的参数是多个的时候,我们一般把它们封装成一个Map了,此时属性值为map其中的一个key

栗子1

当入参为list时

<select id="getUSerByRoleId_foreach_list" resultMap="userMapByRole">
        select * from smbms_user where userRole in
        <!-- 因为此处用了in,因此以 "("开头  ,")"结尾 ,","分隔 -->
        <foreach collection="list" item="roleList" open="(" separator="," close=")">
            #{roleList}
        </foreach>
    </select>

栗子2

当入参为数组时

<select id="getUserByRoleId_foreach_array" resultMap="userMapByRole">
        select * from smbms_user where userRole in
        <!-- 因为此处用了in,因此以 "("开头  ,")"结尾 ,","分隔 -->
        <foreach collection="array" item="roleIds" open="(" separator="," close=")">
            #{roleIds}
        </foreach>
    </select>

栗子3

当为map时

<select id="getProvider"  resultMap="providerresult">
        SELECT * FROM smbms_bill b JOIN smbms_provider p  ON b.providerId=p.id
        where b.providerId in
        <!-- 因为此处用了in,因此以 "("开头  ,")"结尾 ,","分隔 此时的collection的值是map其中的一个key-->
        <foreach collection="#{bibli}" item="pros" open="(" separator="," close=")">
            <!-- 获取对象当中的属性 -->
            #{pros.providerId}    
        </foreach>
    </select>

7 小结

  • if+set:动态完成更新操作
  • if+where:动态完成多条件查询
  • if+trim:完成多条件查询(代替where)或者更新操作(代替set)
  • choose(when,otherwise):动态完成多条件查询(多选一)
  • foreach:主要用于in条件查询中,迭代集合,最关键的部分为collection属性,根据不同的入参类型,该属性值则不同
    1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
    2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
    3. 如果传入的参数是多个的时候,我们一般把它们封装成一个Map了,此时属性值为map其中的一个key

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

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

相关文章

[论文阅读笔记26]Tracking Everything Everywhere All at Once

论文地址: 论文 代码地址: 代码 这是一篇效果极好的像素级跟踪的文章, 发表在ICCV2023, 可以非常好的应对遮挡等情形, 其根本的方法在于将2D点投影到一个伪3D(quasi-3D)空间, 然后再映射回去, 就可以在其他帧中得到稳定跟踪. 这篇文章的方法不是很好理解, 代码也刚开源, 做一…

Git工作流

实际开发项目使用到的分支: main&#xff1a;生产环境&#xff0c;也就是你们在网上可以下载到的版本&#xff0c;是经过了很多轮测试得到的稳定版本。 release&#xff1a; 开发内部发版&#xff0c;也就是测试环境。 dev&#xff1a;所有的feature都要从dev上checkout。 fea…

【C51 GPIO的原理和内部结构】

51单片机项目基础篇 中篇&#xff1a;介绍GPIO1、认识GPIO2、GPIO 结构框图与工作原理2.1、P0端口结构框图与工作原理2.1.1、剖析组成 P0 口的每个单元的作用2.1.2、 P0 口做为 I/O 口及地址/数据总线使用时的具体工作过程 2.2、P1 端口结构框图与工作原理2.3、P2 端口结构框图…

求生之路2社区服务器sourcemod安装配置搭建教程centos

求生之路2社区服务器sourcemod安装配置搭建教程centos 大家好我是艾西&#xff0c;通过上文我们已经成功搭建了求生之路2的服务端。但是这个服务端是纯净的服务端&#xff0c;就是那种最纯粹的原版。如果想要实现插件、sm开头的命令等功能&#xff0c;需要安装这个sourcemod。…

JavaScript(笔记)

目录 Hello World JavaScript 的变量 JavaScript 动态类型 隐式类型转换 JavaScript 数组 JavaScript 函数 JavaScript 中变量的作用域 对象 DOM 选中页面元素 事件 获取 / 修改元素内容 获取 / 修改元素属性 获取 / 修改 表单元素属性 获取 / 修改样式属性 新…

如何可以管理监督员工工作微信?

自从微信管理系统研发上线之后&#xff0c;为了各企业带来了福音。 很多用户企业都是这样评论微信管理系统的&#xff1a;员工的所有微信聊天记录后台都可以清楚明了的看到&#xff0c;聊天记录都是永久保存的&#xff0c;不担心员工在手机上把聊天记录删除&#xff0c;杜绝员…

基于黑猩猩算法优化的BP神经网络(预测应用) - 附代码

基于黑猩猩算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于黑猩猩算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.黑猩猩优化BP神经网络2.1 BP神经网络参数设置2.2 黑猩猩算法应用 4.测试结果&#xff1a;5.Matlab代…

MyBatis 的关联关系配置 一对多,一对一,多对多 关系的映射处理

目录 一.关联关系配置的好处 二. 导入数据库表&#xff1a; 三. 一对多关系&#xff1a;-- 一个订单对应多个订单项 四.一对一关系&#xff1a;---一个订单项对应一个订单 五.多对多关系&#xff08;两个一对多&#xff09; 一.关联关系配置的好处 MyBatis是一…

Java——它要求用户输入一个整数(实际上是一个字符串),然后计算该整数的平方值,并将结果输出。

这是一个Java程序&#xff0c;它要求用户输入一个整数&#xff08;实际上是一个字符串&#xff09;&#xff0c;然后计算该整数的平方值&#xff0c;并将结果输出。程序的基本流程如下&#xff1a; 首先&#xff0c;声明并初始化变量data和result&#xff0c;它们的初始值都为…

咸鱼之王俱乐部网站开发

我的俱乐部 最新兑换码 *注意区分大小写&#xff0c;中间不能有空格&#xff01; APP666 HAPPY666 QQ888 QQXY888 vip666 VIP666 XY888 app666 bdvip666 douyin666 douyin777 douyin888 happy666 huhushengwei888 taptap666 周活动 宝箱周 宝箱说明 1.木质宝箱开启1个…

Netty入门学习和技术实践

Netty入门学习和技术实践 Netty1.Netty简介2.IO模型3.Netty框架介绍4. Netty实战项目学习5. Netty实际应用场景6.扩展 Netty 1.Netty简介 Netty是由JBOSS提供的一个java开源框架&#xff0c;现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具&…

nuxt.js框架使用swiper的5.4.5版本记录,创建广告位幻灯片

nuxt依赖 “nuxt”: “^2.15.8”, “swiper”: “^5.4.5”, “vue”: “^2.7.10”, “vue-awesome-swiper”: “^4.1.1”, 需要完成的效果是 参考地址&#xff1a;https://3.swiper.com.cn/demo/pcSlide/ nuxt代码&#xff1a; <template><div class"page&quo…

基于AI + Milvus Cloud拓展更多、更丰富的AI应用场景

项目后续:探索更多应用场景 欢迎大家基于本项目拓展更多、更丰富的应用场景,例如: 进一步延伸对比功能,例如将不同的单品归类到一起。同样,也可以上传更多图像到数据库中,丰富查询结果。 将本项目转变为时尚探测仪或者时尚推荐系统。例如,将明星图像替换成可购买的…

软件开发的201个原则 阅读笔记 第172-201个原则

目录 原则172 做项目总结 第8章 产品保证原则 原则173 产品保证并不是奢侈品 原则 174 尽早建立软件配置管理过程 原则175 使软件配置管理适应软件过程 原则176 组织SCM 独立于项目管理 原则 177 轮换人员到产品保证组织 给所有中间产品一个名称和版本 原则179 控制基准 原则…

五、多表查询-4.1子查询和分类

一、概念 SQL语句中嵌套select语句&#xff0c;成为嵌套查询&#xff0c;又称子查询。 子查询外部的语句 可以是 insert / update / delete / select 的任何一个。 二、子查询分类 1、根据子查询结果不同 标量子查询&#xff08;子查询结果为单个值&#xff09;、列子查询&a…

Xmind软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 XMind是一款非常流行的思维导图软件&#xff0c;可以帮助用户创建清晰、美观的思维导图&#xff0c;用于记录、整理思维和团队协作。以下是关于XMind软件的详细介绍。 1、XMind的历史和演变 XMind是由北京心图科技有限公司开发…

算法通过村第8关【青铜】| 二叉树的经典算法题

二叉树的双指针 1.相同的树 思路&#xff1a;递归的挨个比较是否相同 class Solution {public boolean isSameTree(TreeNode p, TreeNode q) {if((p null&&q!null) || (p ! null && q null) || (p!null&&q!null&&p.val ! q.val)){return f…

安全帽穿戴检测人脸闸机联动

安全帽穿戴检测人脸闸机联动系统实通过yolov8网络深度学习算法模型&#xff0c;安全帽穿戴检测人脸闸机联动系统现对进入工地施工区域人员是否穿戴安全帽进行精准监测和身份识别&#xff0c;只有在满足这两个条件的情况下&#xff0c;闸机才会打开&#xff0c;允许其进入工地施…

器件介绍TMP1826NGRR、TMP1826DGKR、TMP1827NGRR、TMP1075NDRLR数字温度传感器

一、TMP1826 具有 2Kb EEPROM 的 1-Wire、0.2C 精度温度传感器 器件介绍 TMP1826 是一款高精度、1-Wire 兼容的数字输出温度传感器&#xff0c;具有集成的 2Kb EEPROM 和 –55C 至150C 的宽工作温度范围。TMP1826 在 10C 至45C 的温度范围内提供 0.1C&#xff08;典型值&#…

如何搭建数字化招商加盟体系?如何推动企业招商加盟增速?

线索转化率低、客户数据不完整及合作过程中服务满意度低等情景是企业在进行招商加盟的过程中常常会遇到的问题。如何使用数字化招商加盟工具&#xff0c;在业务运营的过程中来提高企业成单率、提高企业线索价值&#xff0c;提高客户满意度&#xff1f; 开利网络数字化招商加盟系…