当前位置: 首页 > news >正文

MyBatis学习笔记(十) —— 动态SQL

10、动态SQL

MyBatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决拼接SQL语句字符串的痛点问题。

动态SQL:

1、if 标签:通过test属性中的表达式判断标签中的内容是否有效(是否会拼接到sql中)

2、where 标签:

​ a.若where标签中有条件成立,会自动生成where关键字

​ b.会自动将where标签中内容前多余的and去掉,但是其中内容后多余的and无法去掉

​ c.若where标签中没有任何一个条件成立,则where没有任何功能

3、trim 标签

​ prefix、suffix: 在标签中内容前面或后面添加指定内容

​ prefixOverrides、suffixOverrides: 在标签中内容前面或后面去掉指定内容

4、choose、when、otherwise

​ 相当于java中的if…else if…else

5、foreach 标签

collection: 设置要循环的数据或集合

item: 用一个字符串表示数组或集合中的每一个数据

separator: 设置每次循环的数据之间的分隔符

open: 循环的所有内容以什么开始

close: 循环的所有内容以什么结束

6、可以记录一段sql,在需要用的地方使用include标签进行引用。

10.1、if 标签

if标签可通过test属性的表达式进行判断,判断标签中的内容是否有效(是否会拼接到sql中),若表达式的结果为true,这标签中的内容会执行;反之标签中的内容不会执行

Emp.java

package com.fan.mybatis.pojo;/*** @Date: 2023/03/01* @Author: fan* @Description:*/
public class Emp {private Integer empId;private String empName;private Integer age;private String gender;public Emp() {}public Emp(Integer empId, String empName, Integer age, String gender) {this.empId = empId;this.empName = empName;this.age = age;this.gender = gender;}public Integer getEmpId() {return empId;}public void setEmpId(Integer empId) {this.empId = empId;}public String getEmpName() {return empName;}public void setEmpName(String empName) {this.empName = empName;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}@Overridepublic String toString() {return "Emp{" +"empId=" + empId +", empName='" + empName + '\'' +", age=" + age +", gender='" + gender + '\'' +'}';}
}

DynamicSQLMapper.java

package com.fan.mybatis.mapper;import com.fan.mybatis.pojo.Emp;import java.util.List;/*** @Date: 2023/03/01* @Author: fan* @Description:*/
public interface DynamicSQLMapper {/*** 根据条件查询员工信息* @param emp* @return*/List<Emp> getEmpByCondition(Emp emp);
}

DynamicSQLMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.DynamicSQLMapper"><select id="getEmpByCondition" resultType="Emp">select * from t_emp where<if test="empName !=null and empName != ''">emp_name = #{empName}</if><if test="age != null and age != ''">and age = #{age}</if><if test="gender != null and gender != ''">and gender = #{gender}</if></select>
</mapper>

DynamicSQLMapperTest.java

package com.fan.mybatis.test;import com.fan.mybatis.mapper.DynamicSQLMapper;
import com.fan.mybatis.pojo.Emp;
import com.fan.mybatis.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;import java.util.List;public class DynamicMapperTest {@Testpublic void testGetEmpByCondition(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);Emp emp = new Emp(null,"张三",23,"男");List<Emp> list = mapper.getEmpByCondition(emp);list.forEach(System.out::println);}
}

运行测试:

img

10.2、where 标签

where和if一般结合使用:

a>若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字

b>若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的

and去掉

注意:where标签不能去掉条件最后多余的and

where标签主要是解决多条件查询拼接的问题。

@Test
public void testGetEmpByCondition(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);Emp emp = new Emp(null,"",null,"");List<Emp> list = mapper.getEmpByCondition(emp);list.forEach(System.out::println);
}

第一种方式:添加恒成立的条件 1=1

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.DynamicSQLMapper"><select id="getEmpByCondition" resultType="Emp">select * from t_emp where 1=1<if test="empName !=null and empName != ''">and emp_name = #{empName}</if><if test="age != null and age != ''">and age = #{age}</if><if test="gender != null and gender != ''">and gender = #{gender}</if></select>
</mapper>

第二种方式:where标签选择动态生成where关键字

<select id="getEmpByCondition" resultType="Emp">select * from t_emp<where><if test="empName !=null and empName != ''">emp_name = #{empName}</if><if test="age != null and age != ''">and age = #{age}</if><if test="gender != null and gender != ''">and gender = #{gender}</if></where>
</select>

img

10.3、trim 标签

trim用于去掉或添加标签中的内容

常用属性:

prefix:在trim标签中的内容的前面添加某些内容

prefixOverrides:在trim标签中的内容的前面去掉某些内容

suffix:在trim标签中的内容的后面添加某些内容

suffixOverrides:在trim标签中的内容的后面去掉某些内容

<select id="getEmpByCondition" resultType="Emp">select * from t_emp<trim prefix="where" suffixOverrides="and"><if test="empName !=null and empName != ''">emp_name = #{empName}</if><if test="age != null and age != ''">and age = #{age}</if><if test="gender != null and gender != ''">and gender = #{gender}</if></trim>
</select>

运行测试:

img

10.4、choose、when、otherwise 标签

choose、when、otherwise

相当于java中的if…else if…else

when 至少设置一个,otherwise最多设置一个

/**
* 使用choose查询员工信息
* @param emp
* @return
*/
List<Emp> getEmpByChoose(Emp emp);
<select id="getEmpByChoose" resultType="Emp">select * from t_emp<where><choose><when test="empName != null and empName != ''">emp_name = #{empName}</when><when test="age != null and age != ''">age = #{age}</when><when test="gender != null and gender != ''">gender = #{gender}</when></choose></where>
</select>

10.5、foreach 标签

foreach标签

collection: 设置要循环的数据或集合

item: 用一个字符串表示数组或集合中的每一个数据

separator: 设置每次循环的数据之间的分隔符

open: 循环的所有内容以什么开始

close: 循环的所有内容以什么结束

10.5.1、批量添加

DynamicSQLMapper.java

/**
* 批量添加员工信息
* @param emps
*/
void insertMoreEmp(@Param("emps") List<Emp> emps);

DynamicSQLMapper.xml

<insert id="insertMoreEmp">insert into t_emp values<foreach collection="emps" item="emp" separator=",">(null,#{emp.empName},#{emp.age},#{emp.gender},null)</foreach>
</insert>

DynamicSQLMapperTest.java

@Test
public void testInsertMoreEmp(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);Emp emp1 = new Emp(null,"小明1",20,"男");Emp emp2 = new Emp(null,"小明2",20,"男");Emp emp3 = new Emp(null,"小明3",20,"男");List<Emp> list = Arrays.asList(emp1,emp2,emp3);mapper.insertMoreEmp(list);
}

运行测试,控制台输出结果如下:

img

查看数据库可以看到批量添加了3条数据

img

10.5.2、批量删除

DynamicSQLMapper.java

/**
* 批量删除
* @param empIds
*/
void deleteMoreEmp(@Param("empIds") Integer[] empIds);

DynamicSQLMapper.xml

批量删除的第一种写法:

<delete id="deleteMoreEmp">delete from t_emp where emp_id in(<foreach collection="empIds" item="empId" separator=",">#{empId}</foreach>)
</delete>

批量删除的第二种写法:

<delete id="deleteMoreEmp">delete from t_emp where emp_id in<foreach collection="empIds" item="empId" separator="," open="(" close=")">#{empId}</foreach>
</delete>

批量删除的第三种写法:

<delete id="deleteMoreEmp">delete from t_emp where<foreach collection="empIds" item="empId" separator="or">emp_id = #{empId}</foreach>
</delete>

DynamicSQLMapperTest.java

@Test
public void testDeleteMoreEmp() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);Integer[] empIds = new Integer[]{6,7};mapper.deleteMoreEmp(empIds);
}

运行测试,控制台输出如下

img

从数据库中可以看到批量删除了2条数据。

img

10.6、sql 标签

可以记录一段sql,在需要用的地方使用include标签进行引用。

<sql id="empColumns">emp_id,emp_name,age
</sql><select id="getEmpByCondition" resultType="Emp">select <include refid="empColumns"></include> from t_emp<trim prefix="where" suffixOverrides="and"><if test="empName !=null and empName != ''">emp_name = #{empName}</if><if test="age != null and age != ''">and age = #{age}</if><if test="gender != null and gender != ''">and gender = #{gender}</if></trim>
</select>

img

相关文章:

MyBatis学习笔记(十) —— 动态SQL

10、动态SQL MyBatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能&#xff0c;它存在的意义是为了解决拼接SQL语句字符串的痛点问题。 动态SQL&#xff1a; 1、if 标签&#xff1a;通过test属性中的表达式判断标签中的内容是否有效&#xff08;是否会拼接到sql中…...

剑指 Offer 55 - II. 平衡二叉树

剑指 Offer 55 - II. 平衡二叉树 难度&#xff1a;easy\color{Green}{easy}easy 题目描述 输入一棵二叉树的根节点&#xff0c;判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1&#xff0c;那么它就是一棵平衡二叉树。 示例 1: 给定二叉树 […...

一文吃透前端低代码的 “神仙生活”

今天来说说前端低代码有多幸福&#xff1f; 低代码是啥&#xff1f;顾名思义少写代码…… 这种情况下带来的幸福有&#xff1a;代码写得少&#xff0c;bug也就越少&#xff08;所谓“少做少错”&#xff09;&#xff0c;因此开发环节的两大支柱性工作“赶需求”和“修bug”就…...

【深度学习】预训练语言模型-BERT

1.BERT简介 BERT是一种预训练语言模型&#xff08;pre-trained language model, PLM&#xff09;&#xff0c;其全称是Bidirectional Encoder Representations from Transformers。下面从语言模型和预训练开始展开对预训练语言模型BERT的介绍。 1-1 语言模型 语言模型 &#xf…...

C++类的组合

C类的组合什么是类的组合初始化参数列表使用类的组合案例分析组合构造和析构顺序问题this指针基本用法和作用什么是类的组合 类的组合就是以另一个对象为数据成员&#xff0c;这种情况称为类的组合 1.优先使用类的组合&#xff0c;而不是继承 2.组合表达式的含义 一部分关系 初…...

2.伪随机数生成器(ctr_drbg)的配置与使用

零、随机数应用 生成盐,用于基于口令的密码 生成密钥,用于加密和认证 生成一次性整数Nonce,防止重放攻击 生成初始化向量IV 构成 种子,真随机数生成器的种子来源于物理现象 内部状态,种子用来初始化内部状态 一、真随机数和伪随机数 1.区别 随机数在安全技术中通常被用于…...

CentOS7 切换图形模式和多用户命令行模式

备注&#xff1a; 主机名 hw 含义&#xff1a;hardware 缩写&#xff0c;意思是硬件&#xff08;物理机&#xff09; 文章目录1、查看源头2、查看当前系统运行模式3、设置系统运行模式为多用户命令行模式4、查看当前系统运行模式5、重启系统6、确认当前系统运行模式7、设置系统…...

在linux上用SDKMan对Java进行多版本管理

在linux上用SDKMan对Java进行多版本管理 有一个工具叫SDKMan&#xff0c;它允许我们这样做。官方网站这样描述: TIP: "SDKMan 是一个工具&#xff0c;用于在大多数基于Unix的系统上管理多个软件开发工具包的并行版本。它提供了一个方便的命令行接口(CLI)和API&#xff0c…...

JSONObject、fastJson(JsonObject)、Gson(JsonObject)区别

概述 Java中并没有内置的 JSON 解析&#xff0c;需要使用第三方类库 fastJson &#xff1a;阿里巴巴的JSON 库&#xff0c;优势在于解析速度快&#xff0c;解析效率高&#xff0c;可以轻松处理大量的 JSON 数据JackSon &#xff1a; 社区十分活跃&#xff0c;spring框架默认使…...

如何在CSDN中使用ChatGPT

本篇文章致力于帮助大家理解和使用ChatGPT&#xff08;现在CSDN改成”C知道“了&#xff09;。简介ChatGPT是OpenAI公司开发的一种大型语言模型。它是一种基于Transformer架构的深度学习模型&#xff0c;可以对语言进行建模和生成。它可以处理问答、对话生成、文本生成等多种任…...

【Spring6】| GoF之工厂模式

目录 一&#xff1a;GoF之工厂模式 1. 工厂模式的三种形态 2. 简单工厂模式 3. 工厂方法模式 4. 抽象工厂模式&#xff08;了解&#xff09; 一&#xff1a;GoF之工厂模式 &#xff08;1&#xff09;GoF&#xff08;Gang of Four&#xff09;&#xff0c;中文名——四人组…...

初识Node.js

文章目录初识Node.jsNode.js简介fs模块演示路径问题path路径模块http模块创建web服务器得基本步骤req请求对象res响应对象解决中文乱码问题模块化的基本慨念1、模块化2、Node.js中模块的分类3、Node.js中的模块作用域3.1什么是模块作用域4、向外共享模块作用域中的成员4.1modul…...

C51---软件消抖

1.example #include "reg52.h" #include "intrins.h" //main.c(11): error C264: intrinsic _nop_: declaration/activation error,添加这个头文件就可了 sbit led1 P3^7;//引脚位置&#xff0c;根据原理图可知 sbit key1 P2^1; sbit key2 P2^0; void …...

redis数据持久化

redis备份概念 Redis所有数据都是保存在内存中&#xff0c;Redis数据备份可以定期的通过异步方式保存到磁盘上&#xff0c;该方式称为半持久化模式&#xff0c;如果每一次数据变化都写入aof文件里面&#xff0c;则称为全持久化模式。同时还可以基于Redis主从复制实现Redis备份…...

Java StringBuffer类

Java StringBuffer类是Java语言中一个非常重要的类&#xff0c;它提供了丰富的方法&#xff0c;可以方便地进行字符串操作。本文将详细介绍Java StringBuffer类的作用以及在实际工作中的用途。 StringBuffer类的作用 Java StringBuffer类是一个可变的字符串缓冲区&#xff0c…...

电路模型和电路定律(2)——“电路分析”

各位CSDN的uu们你们好呀&#xff0c;好久没有更新电路分析的文章啦&#xff0c;今天来小小复习一波&#xff0c;之前那篇博客&#xff0c;小雅兰更新了电路的历史以及电压电流的参考方向&#xff0c;这篇博客小雅兰继续&#xff01;&#xff01;&#xff01; 电阻元件 电压源和…...

天琊超级进程监视器的应用试验(19)

实验目的 1、了解进程概念及其基本原理&#xff1b; 2、掌握天琊超级进程监视器的安装与使用。预备知识 本实验要求实验者具备如下的相关知识。 操作系统的安全配置是整个系统安全审计策略核心&#xff0c;其目的就是从系统根源构筑安全防护体系&#xff0c;通过用户的一…...

使用 Pulumi 打造自己的多云管理平台

前言在公有云技术与产品飞速发展的时代&#xff0c;业务对于其自身的可用性提出了越来越高的要求&#xff0c;当跨区域容灾已经无法满足业务需求的情况下&#xff0c;我们通常会考虑多云部署我们的业务平台&#xff0c;以规避更大规模的风险。但在多云平台部署的架构下&#xf…...

什么是MyBatis?无论是基础教学还是技术精进,你都应该看这篇MyBatis

文章目录学习之前&#xff0c;跟你们说点事情&#xff0c;有助于你能快速看完文章一、先应用再学习&#xff0c;代码示例1. 第一个MyBatis程序2. MyBatis整合Spring3. SpringBoot整合MyBatis二、MyBatis整体流程&#xff0c;各组件的作用域和生命周期三、说说MyBatis-config.xm…...

【编程基础之Python】10、Python中的运算符

【编程基础之Python】10、Python中的运算符Python中的运算符算术运算符赋值运算符比较运算符逻辑运算符位运算符成员运算符身份运算符运算符优先级运算符总结Python中的运算符 Python是一门非常流行的编程语言&#xff0c;它支持各种运算符来执行各种操作。这篇文章将详细介绍…...

请解释 Linux 系统中的内核模块管理,并描述如何加载和卸载模块。

在 Linux 系统中&#xff0c;内核模块&#xff08;Kernel Modules&#xff09; 是可以在不重新编译或重启内核的情况下&#xff0c;动态添加到运行中内核的代码片段。它们通常用于支持新的硬件设备、文件系统或网络协议。 这种机制使得 Linux 内核保持精简&#xff08;核心功能…...

别再用默认字典了!DVWA暴力破解实战:从Low到High,手把手教你配置Burp Suite的Pitchfork模式

别再用默认字典了&#xff01;DVWA暴力破解实战&#xff1a;从Low到High&#xff0c;手把手教你配置Burp Suite的Pitchfork模式 在渗透测试的入门阶段&#xff0c;暴力破解往往是最先接触的攻击手段之一。但许多新手在DVWA的High级别面前束手无策——那些看似简单的登录表单&am…...

离线语音智能处理平台Buzz:本地化音频转文本全攻略

离线语音智能处理平台Buzz&#xff1a;本地化音频转文本全攻略 【免费下载链接】buzz Buzz transcribes and translates audio offline on your personal computer. Powered by OpenAIs Whisper. 项目地址: https://gitcode.com/GitHub_Trending/buz/buzz 在当今信息驱动…...

从LVGL V7.11到V9.1:我维护中文文档这三年踩过的坑与实战经验

从LVGL V7.11到V9.1&#xff1a;一个中文文档维护者的技术叙事 三年前&#xff0c;当我第一次在嵌入式项目中尝试使用LVGL时&#xff0c;完全没想到这个轻量级图形库会成为我技术生涯中的重要篇章。作为国内最早系统维护LVGL中文文档的开发者之一&#xff0c;这段跨越三个大版本…...

League Akari:英雄联盟玩家的终极自动化工具包

League Akari&#xff1a;英雄联盟玩家的终极自动化工具包 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power &#x1f680;. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League Akari 是一款基于官方 LCU A…...

ANSYS CFX 自定义函数实战:数据导入与变量创建全流程

1. ANSYS CFX自定义函数入门指南 第一次接触CFX自定义函数时&#xff0c;我也被那一堆参数和选项搞得晕头转向。但实际用下来发现&#xff0c;这玩意儿就像给计算流体力学(CFD)分析装了个"外挂"&#xff0c;能让你在标准功能之外实现各种个性化需求。简单来说&#x…...

实战开发:基于快马AI为mc jc服务器快速生成定制化空岛生存玩法插件

今天想和大家分享一个实战案例&#xff1a;如何用InsCode(快马)平台为我的MC JC服务器快速开发一个定制化的空岛生存玩法插件。整个过程比想象中顺利很多&#xff0c;特别适合需要快速迭代玩服的服主们。 需求分析阶段 空岛生存模式需要解决四个核心问题&#xff1a;初始环境生…...

单机变联机:Nucleus Co-Op如何让你的电脑实现4人同屏游戏

单机变联机&#xff1a;Nucleus Co-Op如何让你的电脑实现4人同屏游戏 【免费下载链接】nucleuscoop Starts multiple instances of a game for split-screen multiplayer gaming! 项目地址: https://gitcode.com/gh_mirrors/nu/nucleuscoop 你是否曾想过&#xff0c;用一…...

如何用Mermaid Live Editor 5分钟创建专业图表

如何用Mermaid Live Editor 5分钟创建专业图表 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid-live-editor Mermaid Live…...

基于Simulink的自抗扰控制(ADRC)在OBC前级的应用

手把手教你学Simulink——基于Simulink的自抗扰控制(ADRC)在OBC前级的应用​ (附:OBC前级拓扑剖析+ADRC抗扰原理+TD/ESO/NLSEF算法推导+Simulink全模型搭建+动态响应/谐波抑制对比+实机部署指南) 摘要​ 车载充电机(OBC)前级作为交流-直流(AC-DC)整流核心,需将电网…...