【JavaWeb】Day51.Mybatis动态SQL

 什么是动态SQL

在页面原型中,列表上方的条件是动态的,是可以不传递的,也可以只传递其中的1个或者2个或者全部。

而在我们刚才编写的SQL语句中,我们会看到,我们将三个条件直接写死了。 如果页面只传递了参数姓名name 字段,其他两个字段 性别 和 入职时间没有传递,那么这两个参数的值就是null。

此时,执行的SQL语句为:

这个查询结果是不正确的。正确的做法应该是:传递了参数,再组装这个查询条件;如果没有传递参数,就不应该组装这个查询条件。

SQL语句会随着用户的输入或外部条件的变化而变化,我们称为:动态SQL。

在Mybatis中提供了很多实现动态SQL的标签,我们学习Mybatis中的动态SQL就是掌握这些动态SQL标签。

动态SQL-if

<if>:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL。

~~~xml

<if test="条件表达式">

要拼接的sql语句

</if>

接下来,我们就通过`<if>`标签来改造之前条件查询的案例。

条件查询

示例:把SQL语句改造为动态SQL方式

- 原有的SQL语句

~~~xml
<select id="list" resultType="com.itheima.pojo.Emp">select * from empwhere name like concat('%',#{name},'%')and gender = #{gender}and entrydate between #{begin} and #{end}order by update_time desc
</select>
~~~

- 动态SQL语句

~~~xml
<select id="list" resultType="com.itheima.pojo.Emp">select * from empwhere<if test="name != null">name like concat('%',#{name},'%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null">and entrydate between #{begin} and #{end}</if>order by update_time desc
</select>
~~~

测试方法:

~~~java
@Test
public void testList(){//性别数据为null、开始时间和结束时间也为nullList<Emp> list = empMapper.list("张", null, null, null);for(Emp emp : list){System.out.println(emp);}
}
~~~

执行的SQL语句:

下面呢,我们修改测试方法中的代码,再次进行测试,观察执行情况:

~~~java
@Test
public void testList(){//姓名为nullList<Emp> list = empMapper.list(null, (short)1, null, null);for(Emp emp : list){System.out.println(emp);}
}
~~~

执行结果:

再次修改测试方法中的代码,再次进行测试:

~~~java
@Test
public void testList(){//传递的数据全部为nullList<Emp> list = empMapper.list(null, null, null, null);for(Emp emp : list){System.out.println(emp);}
}
~~~

执行的SQL语句:

以上问题的解决方案:使用`<where>`标签代替SQL语句中的where关键字

         `<where>`只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或OR。

~~~xml
<select id="list" resultType="com.itheima.pojo.Emp">select * from emp<where><!-- if做为where标签的子元素 --><if test="name != null">and name like concat('%',#{name},'%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null">and entrydate between #{begin} and #{end}</if></where>order by update_time desc
</select>
~~~

测试方法:

~~~java
@Test
public void testList(){//只有性别List<Emp> list = empMapper.list(null, (short)1, null, null);for(Emp emp : list){System.out.println(emp);}
}
~~~

执行的SQL语句:

案例:更新员工

案例:完善更新员工功能,修改为动态更新员工数据信息

使用动态SQL更新员工信息,如果更新时传递有值,则更新;如果更新时没有传递值,则不更新。

修改Mapper接口:

~~~java
@Mapper
public interface EmpMapper {//删除@Update注解编写的SQL语句//update操作的SQL语句编写在Mapper映射文件中public void update(Emp emp);
}
~~~

修改Mapper映射文件:

~~~xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper"><!--更新操作--><update id="update">update empset<if test="username != null">username=#{username},</if><if test="name != null">name=#{name},</if><if test="gender != null">gender=#{gender},</if><if test="image != null">image=#{image},</if><if test="job != null">job=#{job},</if><if test="entrydate != null">entrydate=#{entrydate},</if><if test="deptId != null">dept_id=#{deptId},</if><if test="updateTime != null">update_time=#{updateTime}</if>where id=#{id}</update></mapper>
~~~

测试方法:

~~~java
@Test
public void testUpdate2(){//要修改的员工信息Emp emp = new Emp();emp.setId(20);emp.setUsername("Tom111");emp.setName("汤姆111");emp.setUpdateTime(LocalDateTime.now());//调用方法,修改员工数据empMapper.update(emp);
}
~~~

执行的SQL语句:

再次修改测试方法,观察SQL语句执行情况:

~~~java
@Test
public void testUpdate2(){//要修改的员工信息Emp emp = new Emp();emp.setId(20);emp.setUsername("Tom222");//调用方法,修改员工数据empMapper.update(emp);
}
~~~

执行的SQL语句:

以上问题的解决方案:使用`<set>`标签代替SQL语句中的set关键字

`<set>`:动态的在SQL语句中插入set关键字,并会删掉额外的逗号。(用于update语句中)

~~~xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper"><!--更新操作--><update id="update">update emp<!-- 使用set标签,代替update语句中的set关键字 --><set><if test="username != null">username=#{username},</if><if test="name != null">name=#{name},</if><if test="gender != null">gender=#{gender},</if><if test="image != null">image=#{image},</if><if test="job != null">job=#{job},</if><if test="entrydate != null">entrydate=#{entrydate},</if><if test="deptId != null">dept_id=#{deptId},</if><if test="updateTime != null">update_time=#{updateTime}</if></set>where id=#{id}</update>
</mapper>
~~~

再次执行测试方法,执行的SQL语句:

小结

`<if>`

  - 用于判断条件是否成立,如果条件为true,则拼接SQL

  - 形式:

 ~~~xml<if test="name != null"> … </if>~~~

 `<where>`

  - where元素只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或OR

 `<set>`

  - 动态地在行首插入 SET 关键字,并会删掉额外的逗号。(用在update语句中)

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

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

相关文章

flutter 实现表单的封装包含下拉框和输入框

一、表单封装组件实现效果 //表单组件 Widget buildFormWidget(List<InputModel> formList,{required GlobalKey<FormState> formKey}) {return Form(key: formKey,child: Column(children: formList.map((item) {return Column(crossAxisAlignment: CrossAxisAlig…

java优先级队列(堆)详解

一、优先级概念 什么是优先级&#xff1a;比如女士优先&#xff0c;个子低的优先排到前面去&#xff0c;有一部分数据具备优先级&#xff0c;要以优先级的顺序将顺序存储起来。 前面介绍过队列&#xff0c;队列是一种先进先出(FIFO)的数据结构&#xff0c;但有些情况下&#…

Java:String类

目录 1.String类的重要性2.String对象的比较2.1 比较是否引用同一个对象2.2 boolean equals(Object anObject) 方法&#xff1a;按照字典序比较2.3int compareTo(String s)方法: 按照字典序进行比较2.4 boolean equalsIgnoreCase(Object anObject)方法&#xff1a;忽略大小写的…

word批量修改表格样式

利用宏&#xff0c;批量选中表格&#xff0c;然后利用段落和表设计来操作。 利用宏&#xff0c;批量选中表格&#xff0c;参考百度安全验证段落&#xff0c;表格里面的内容有空格&#xff0c;应该是有缩进&#xff0c;在段落中去掉缩进&#xff0c;即缩进-特殊&#xff0c;选择…

node的事件循环

异步同步啥的就不多说了&#xff0c;直接看node中有哪些是异步 其中灰色部分和操作系统有很大的关系&#xff0c;就不多说了&#xff0c;其中定时器属于timers队列&#xff0c;I/O操作属于poll队列&#xff0c;setImmediate属于check队列&#xff0c;其中nextTick和promise不属…

【Java IO】那字节流和字符流有什么区别?

&#x1f331;以贴近现实的【面试官面试】形式涵盖大部分Java程序员需要掌握的后端知识、面试问题&#xff0c;系列博客收录在我开源的JavaGetOffer中&#xff0c;会一直完善下去&#xff0c;希望收到大家的 ⭐️ Star ⭐️支持&#xff0c;这是我创作的最大动力&#xff1a; h…

2024团体程序设计天梯赛L1-101 别再来这么多猫娘了!

题目链接L1-101 别再来这么多猫娘了&#xff01; #include<iostream> #include<stdio.h> #include<string.h> #include<string> #include<algorithm> using namespace std; string s[105], text; int n, k, ans, a[5005];int main() { // ios::s…

第21天:信息打点-公众号服务Github监控供应链网盘泄漏证书图标邮箱资产

第二十一天 一、开发泄漏-Github监控 1.短期查看 1.密码搜索 根据攻击目标的域名在GitHub上进行搜索密码&#xff0c;如果目标网站的文件与搜索到的源码相关&#xff0c;那就可以联想目标网站是否使用这套源码进行开发 原理就是开发者在上传文件的时候忘记更改敏感文件或者…

利用FFmpeg 转换课程vtt 字幕到 srt字幕

字幕转换工具 经常学习udemy 视频课程的&#xff0c;可能知道&#xff0c;从网络下载的udemy 课程文件里面有时候字幕是vtt 格式的&#xff0c;有时候想导入到百度网盘里面&#xff0c;怎奈百度网盘&#xff0c;不支持vtt 字幕格式。有字幕的时候&#xff0c;会比较好多了。既可…

【机器学习】《ChatGPT速通手册》笔记

文章目录 第0章 前言第1章 ChatGPT的由来&#xff08;一&#xff09;自然语言处理任务&#xff08;二&#xff09;ChatGPT所用数据数据大小&#xff08;三&#xff09;ChatGPT的神经网络模型有175亿个参数&#xff08;四&#xff09;模型压缩 方案 第2章 ChatGPT页面功能介绍&a…

日期相关的题目

日期相关的题目 1. 计算日期到天数转换2. 日期累加3. 打印日期4. 日期差值 1. 计算日期到天数转换 输出示例: 思路&#xff1a;计算前n-1个月的天数在加上这个月的天数。 #include <iostream> using namespace std;int main() {int year, month, day;cin >> yea…

llama2 与 llama3比较

Llama 3 刚刚在4月18号推出&#xff0c;距 Llama 2 发布正好 9 个月。它已经可以在 Meta 网站上进行聊天&#xff0c;可以从 Huggingface 以 safetensors 或 GGUF 格式下载。 llama 2 与 llama3 比较 1. 模型输出&#xff08;model output&#xff09; llama 2 输出只能是文本…

const成员函数 以及 取地址及const取地址操作符重载

目录 const成员函数 结论&#xff1a; 取地址及const取地址操作符重载 const成员函数 将const 修饰的 “ 成员函数 ” 称之为 const成员函数 &#xff0c; const 修饰类成员函数&#xff0c;实际修饰该成员函数的&#xff08;*this&#xff09; &#xff0c;表明在该成员函数…

网络原理-IP协议

一、IP协议报头 版本号:用来表示IP协议的版本,现在常用的IP协议有两个版本,IPv4和IPv6&#xff0c;其他版本可能只存在于实验室中&#xff0c;并没有被广泛的使用。 首部长度:用来表示IP报头的长度,因为存在"选项"字段&#xff0c;所以IP报头是可变长的,此处单位为4…

日期类的实现

目录 Date.h Test.cpp 测试代码Test.cpp 日期类的实现 代码分享 Date.h #pragma once #include<iostream> using namespace std; #include<assert.h>class Date {//友元函数声明friend ostream& operator<<(ostream& out, Date& d);friend…

[渗透测试学习] Headless-HackTheBox

Headless-HackTheBox 信息搜集 使用nmap扫描一下 nmap -sV -sC -v --min-rate 1000 10.10.11.8可以发现5000端口是开放的,继续扫一下目录 访问/dashboard发现只有admin才可以,我们注意到cookie值为JWT加密,拿到揭秘网站验证下猜想 cookie为user用户,那么我们要想访问必须…

[阅读笔记29][AgentStudio]A Toolkit for Building General Virtual Agents

这篇论文是24年3月提交的&#xff0c;提出了一个用于agent开发的全流程工具包。 作者提到目前agent开发主要有两个阻碍&#xff0c;一个是缺乏软件基础&#xff0c;另一个是缺乏在真实世界场景中进行评估。针对这两个阻碍&#xff0c;作者涉及了一个开发工具包&#xff0c;包括…

[已解决]react打包部署

react打包部署 问题 npm install 命令无反应 思路 换成 yarn install 安装完hadoop的环境后&#xff0c;使用node的yarn会报错&#xff1a; 我们在cmd使用where yarn&#xff0c;如下&#xff1a; 看你想保留哪一个&#xff0c;我平时node用的多&#xff0c;就把hadoop的y…

项目小游戏-贪吃蛇

目录 1.游戏开始 - GameStart 1.1cmd命令窗口 调节窗口命令 ​编辑更改窗口命名 ​编辑 1.2 Win32 API win32 API 的介绍: ​编辑 获取控制台坐标COORD 获取控制台句柄: 获取缓冲台光标信息: 获取虚拟键位: 本地初始化 setlocale(); 游戏开始的具体实现&#xff1a…

使用AOP切面做防止用户重复提交功能

在我们的项目中&#xff0c;需要考虑到有时候因为网络原因或者其他原因用户对同一个接口进行同一批数据的重复性操作&#xff0c;如果不做这样的处理很可能会在数据库中添加多条同样的数据。 我们可以通过使用aop来解决这样的问题&#xff0c;接下来看看具体怎么做吧~ 自定义…