【Mybatis篇】动态SQL的详细带练

      🧸安清h:个人主页

   🎥个人专栏:【计算机网络】

🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。

文章目录

🎯一.动态SQL简单介绍

🚦动态SQL的基本概念

🎯二.条件查询操作

🚦数据库准备

🚦POJO类准备

🚦创建映射文件(元素)

🚦修改核心配置文件

🚦创建MybatisUtil工具类

🚦创建接口类 

🚦修改测试类

✨,,元素

✨更新操作 

✨复杂查询操作 

🍔元素简单介绍

🍔元素迭代List

 🍔元素迭代数组

 🍔元素迭代Map

🎯总结


🎯一.动态SQL简单介绍

动态SQL是MyBatis框架中一个非常强大的特性,它允许开发者在构建SQL语句时根据条件动态地生成不同的SQL片段。这样做的好处是可以避免硬编码查询逻辑,简化数据库查询的复杂度,同时提高代码的可读性和维护性。

🚦动态SQL的基本概念

动态SQL并不是一个新的概念,它指的是在运行时根据条件构建SQL语句,而不是使用静态的SQL语句。MyBatis通过一系列的动态SQL标签来实现这一功能,这些标签包括:

  • <if>:根据条件动态拼接SQL。
  • <choose><when><otherwise>:类似于Java中的switch-case语句。
  • <trim><where><set>:用于处理SQL语句的不同部分,如自动添加WHERE,并去除多余的AND。
  • <foreach>:用于处理集合,生成IN查询。

🎯二.条件查询操作

🚦数据库准备

在数据库mybatis下,创建一个customer表,并向其中插入几条数据,代码如下:

create table customer(id int(32) primary key auto_increment,username varchar(50),jobs varchar(50),phone varchar(16)
);insert into customer values ('1','joy','teacher','122222222');
insert into customer values ('2','jack','teacher','133333333');
insert into customer values ('3','tom','worker','1267567567');

🚦POJO类准备

一般放在pojo包里,这里我直接在java包中建立了,类中声明id,username,jobs,phone属性,以及属性相对应get/set方法。

public class Customer {private Integer id;private String username;private String jobs;private String phone;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getJobs() {return jobs;}public void setJobs(String jobs) {this.jobs = jobs;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}@Overridepublic String toString() {return "Customer{" +"id=" + id +", username='" + username + '\'' +", jobs='" + jobs + '\'' +", phone='" + phone + '\'' +'}';}
}

🚦创建映射文件(<if>元素)

if元素中的test属性多用于条件判断语句中,用于判断真假,在此处,我们对用户姓名和工作都做了非空判断,如果传入的查询条件非空就进行动态SQL组装。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="CustomerMapper"><select id="QueryByNameAndJobs" parameterType="Customer" resultType="Customer">select * from customerwhere 1=1<if test="username!=null and username!=''">and username like concat('%',#{username},'%')</if><if test="jobs!=null and jobs!=''">and jobs=#{jobs}</if></select>
</mapper>

🚦修改核心配置文件

在核心配置文件mybatis-config.xml中引入CustomerMapper.xml映射文件,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 配置文件的根元素 -->
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql:///mybatis?characterEncoding=utf-8"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments><mappers><mapper resource="CustomerMapper.xml"/></mappers>
</configuration>

🚦创建MybatisUtil工具类

这段代码的目的是为了封装MyBatis的初始化过程,并提供一个全局访问点来获取SqlSession,使得在应用的其他部分可以很方便地使用MyBatis进行数据库操作,而不需要关心SqlSessionFactory的创建和配置细节。这样做可以减少代码重复,提高代码的可维护性。

public class MybatisUtil {private static SqlSessionFactory sqlSessionFactory=null;static {try {Reader reader= Resources.getResourceAsReader("mybatis-config.xml");sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);} catch (IOException e) {throw new RuntimeException(e);}}public static SqlSession getSession(){return sqlSessionFactory.openSession();}
}

🚦创建接口类 

public interface CustomerMapper {List<Customer> QueryByNameAndJobs(Customer customer);
}

🚦修改测试类

在测试类MybatisTest中,编写测试方法testQuery,该方法用于通过姓名和工作查询客户信息。

public class MybatisTest {@Testpublic void testQuery(){SqlSession sqlSession=MybatisUtil.getSession();CustomerMapper customerMapper=sqlSession.getMapper(CustomerMapper.class);Customer customer=new Customer();customer.setUsername("jack");customer.setJobs("teacher");List<Customer> list=customerMapper.QueryByNameAndJobs(customer);for(Customer c:list){System.out.println(c);}sqlSession.close();}
}

✨<choose>,<when>,<otherwise>元素

在MyBatis的动态SQL中,<choose>, <when>, <otherwise>元素组合用于条件分支选择,类似于Java中的if-elseswitch语句。这些元素允许在SQL语句中根据不同的条件执行不同的SQL片段。

以下是这些元素的基本用法:

  • <choose>元素表示一个条件选择块的开始,它本身不生成任何SQL语句。
  • <when>元素表示一个条件分支,它内部包含一个test属性,该属性用于指定条件表达式。如果test属性中的表达式计算为true,则该分支内的SQL会被包含在最终的SQL语句中。
  • <otherwise>元素表示在所有<when>条件都不满足时执行的分支。它类似于switch语句中的default分支。

(1)在映射文件CustomerMapper.xml中,添加使用 <choose>,<when>,<otherwise>实现以下场景:

  • 在客户名称不为空时,只根据客户名称查找。
  • 客户名称为空,客户职业不为空时,只根据客户职业查找。
  • 客户名称和客户职业都为空时,查询出所有电话不为空的客户信息。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="CustomerMapper"><select id="findByWhere" parameterType="Customer" resultType="Customer">select * from customer where 1=1<choose><when test="username!=null and username!=''">and username like concat('%',#{username},'%')</when><when test="jobs!=null and jobs!=''">and jobs=#{jobs}</when><otherwise>and phone is not null</otherwise></choose></select>
</mapper>

 上述使用<choose>元素进行SQL拼接,当第一个<when>元素中的条件为真时,只动态组装第一个<when>元素内的SQL片段并执行,否则就继续向下判断第二个<when>元素中的条件是否为真,以此类推,直到某个<when>元素中的条件为真,结束判断。当前面所有的<when>元素中的条件都不为真时,则动态组装<otherwise>元素内的SQL片段并执行。

(2)在测试类MybatisTest中,编写测试方法findByWhere(),具体代码如下:

public class MybatisTest {@Testpublic void findByWhere(){SqlSession sqlSession=MybatisUtil.getSession();CustomerMapper customerMapper=sqlSession.getMapper(CustomerMapper.class);Customer customer=new Customer();customer.setUsername("jack");customer.setJobs("teacher");List<Customer> list=customerMapper.findByWhere(customer);for(Customer c:list){System.out.println(c);}sqlSession.close();}
}

不同的查询结果如下:

1.客户姓名不为空时

2.客户姓名为空,客户职业不为空时

3.客户姓名和客户职业都为空时

✨更新操作 

在MyBatis中,<set>标签用于构建动态SQL语句中的UPDATE操作,它允许根据条件动态地更新表中的列。<set>标签会自动地为你插入的每个列添加逗号分隔,并且会忽略空格,使得构建动态更新语句更加方便。

<set>标签通常与<if>标签结合使用,以便在运行时根据条件动态地构建更新的列和值。以下是一个基本的示例:

(1)在映射文件CustomerMapper.xml中,使用<set>元素执行更新操作的动态SQL:

<update id="updateCustomerBySet" parameterType="Customer">update customer<set><if test="username!=null and username!=''">username=#{username},</if><if test="jobs!=null and jobs!=''">jobs=#{jobs}</if><if test="phone!=null and phone!=''">phone=#{phone}</if></set>where id=#{id}</update>

  (2)在CustomerMapper接口中添加如下操作:

public interface CustomerMapper {int updateCustomerBySet(Customer customer);
}

(3)在测试类MybatisTest中编写测试方法testUpdate(),具体实现代码如下:

@Testpublic void testUpdate(){SqlSession sqlSession=MybatisUtil.getSession();CustomerMapper customerMapper=sqlSession.getMapper(CustomerMapper.class);Customer customer=new Customer();customer.setId(3);customer.setPhone("123456789");int rows=customerMapper.updateCustomerBySet(customer);if(rows>0){System.out.println("您修改成功了"+rows+"条数据");}else{System.out.println("您修改失败了!");}sqlSession.commit();sqlSession.close();}

(4)修改成功后就可以看到:

在表中的数据如下图:

 

✨复杂查询操作 

🍔<foreach>元素简单介绍

在MyBatis中,<foreach>标签用于遍历集合,常用于构建IN条件子句或批量操作(如批量插入、更新、删除)。<foreach>标签可以处理集合或数组类型的参数,为每个元素生成SQL片段,并将这些片段组合起来。

属性描述

collection

指定要遍历的集合或数组

item

指定集合中每个元素的别名,可以在遍历块内部使用

index

指定集合中每个元素的索引或键的别名,可以在遍历块内部使用

open

指定遍历输出的开始符号

close

指定遍历输出的结束符号

separator

指定遍历元素之间的分隔符

nullable

指定是否允许collection为空值

 

🍔<foreach>元素迭代List

(1)在映射文件CustomerMapper.xml中,添加使用<foreach>元素迭代List执行批量查询操作,具体代码如下:

<select id="findByArray" resultType="Customer">select * from Customer where id in<foreach item="id" collection="list" open="(" separator="," close=")">#{id}</foreach></select>

(2)在测试类MybatisTest中编写测试方法testforeach(),具体实现代码如下:

    @Testpublic void testforeach(){SqlSession sqlSession=MybatisUtil.getSession();Customer customer=new Customer();List<Integer> ids = new ArrayList<Integer>();ids.add(2);ids.add(3);List<Customer> list=sqlSession.selectList("CustomerMapper.findByArray",ids);for(Customer c:list){System.out.println(c);}sqlSession.close();}

(3)在接口CustomerMapper 中添加以下代码:

List<Customer> findByArray(String customerMapper, List<Integer> ids);

(4)查询结果如下图:

 🍔<foreach>元素迭代数组

(1)在映射文件CustomerMapper.xml中,添加使用<foreach>元素迭代数组执行批量查询操作,具体代码如下:

    <select id="findByList" resultType="Customer">select * from Customer where id in<foreach item="id" collection="list" open="(" separator="," close=")">#{id}</foreach></select>

(2)在测试类MybatisTest中编写测试方法testforeach(),具体实现代码如下:

    @Testpublic void testforeach(){SqlSession sqlSession=MybatisUtil.getSession();Customer customer=new Customer();Integer[] ids={1,2};List<Customer> list=sqlSession.selectList("CustomerMapper.findByList",ids);for(Customer c:list){System.out.println(c);}sqlSession.close();}

 🍔<foreach>元素迭代Map

由于Mybatis传入参数均为一个参数,如果传入参数为多个参数,例如,查询出性别为男性且职业为教师的所有客户信息,此时,需要把这些参数封装成一个Map集合进行处理。

(1)在映射文件CustomerMapper.xml中,添加使用<foreach>元素迭代Map执行批量查询操作,具体代码如下:

<select id="findByMap" parameterType="java.util.Map" resultType="Customer">select * from customer where jobs=#{jobs} and id in<foreach item="roleMap" index="index" collection="id" open="(" separator="," close=")">#{roleMap}</foreach></select>

(2)在测试类MybatisTest中编写测试方法testforeach(),具体实现代码如下:

    @Testpublic void testforeach(){SqlSession sqlSession=MybatisUtil.getSession();List<Integer> ids=new ArrayList<Integer>();ids.add(1);ids.add(2);ids.add(3);Map<String,Object> map=new HashMap<String, Object>();map.put("id",ids);map.put("jobs","teacher");List<Customer> list=sqlSession.selectList("CustomerMapper.findByMap",map);for(Customer c:list){System.out.println(c);}sqlSession.close();}

 

🎯总结


以上就是今天要讲的内容了,主要在<if>,<choose>,<when>,<otherwise>,<foreach>方面做了重点的讲解,非常感谢您的阅读,如果这篇文章对您有帮助,那将是我的荣幸。我们下期再见啦🧸!

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

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

相关文章

【深度】为GPT-5而生的「草莓」模型!从快思考—慢思考到Self-play RL的强化学习框架

原创 超 超的闲思世界 2024年09月11日 19:17 北京 9月11日消息&#xff0c;据外媒The Information昨晚报道&#xff0c;OpenAI的新模型「草莓」&#xff08;Strawberry&#xff09;&#xff0c;将在未来两周内作为ChatGPT服务的一部分发布。 「草莓」项目是OpenAI盛传已久的…

全网最全软件测试面试题(含答案解析+文档)

一、软件测试基础面试题 1、阐述软件生命周期都有哪些阶段? 常见的软件生命周期模型有哪些? 软件生命周期是指一个计算机软件从功能确定设计&#xff0c;到开发成功投入使用&#xff0c;并在使用中不断地修改、增补和完善&#xff0c;直到停止该软件的使用的全过程(从酝酿到…

YOLO V8半自动标注工具设计

前提&#xff1a; 对于某些边界不明确的小目标&#xff0c;要是目标由比较多的话&#xff0c;标注起来就会非常麻烦。 如何利用已有训练模型&#xff0c;生成框&#xff0c;进行预标注。再通过调节预标注框的方式&#xff0c;提高标注的效率。 1 通过预先训练的模型生成yolo 格…

一文上手SpringSecurity【七】

之前我们在测试的时候,都是使用的字符串充当用户名称和密码,本篇将其换成MySQL数据库. 一、替换为真实的MySQL 1.1 引入依赖 <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</v…

Jenkins Pipeline 中通过勾选参数来控制是否构建 Docker 镜像

1.定义参数&#xff1a; 使用 booleanParam 定义一个布尔参数&#xff0c;示例如下 booleanParam(name: BUILD_DOCKER, description: 是否构建Docker镜像, defaultValue: false)2.使用参数&#xff1a; 在 stage 中&#xff0c;根据参数的值决定构建方式&#xff1a; stage(编…

python基础库

文章目录 1.研究目的2.platform库介绍3.代码4.结果展示 1.研究目的 最近项目中需要利用python获取计算机硬件的一些基本信息,查阅资料,.于是写下这篇简短的博客,有问题烦请提出,谢谢-_- 2.platform库介绍 platform 库是 Python 的一个内置库&#xff0c;可以让我们轻松地获取…

spring boot 项目中redis的使用,key=value值 如何用命令行来查询并设置值。

1、有一个老项目&#xff0c;用到了网易云信&#xff0c;然后这里面有一个AppKey&#xff0c;然后调用的时候要在header中加入这些标识&#xff0c;进行与服务器进行交互。 2、开发将其存在了redis中&#xff0c;一开始的时候&#xff0c;我们测试用的老的key&#xff0c;然后提…

ValueError: Out of range float values are not JSON compliant

可能原因一 可能原因二 数据里面有NaN

算法: 滑动窗口题目练习

文章目录 滑动窗口长度最小的子数组无重复字符的最长子串最大连续1个个数 III将x减到0的最小操作数水果成篮找到字符串中所有字母异位词串联所有单词的子串最小覆盖子串 总结 滑动窗口 长度最小的子数组 做这道题时,脑子里大概有个印象,知道要用滑动窗口,但是对于滑动窗口为什…

2016年国赛高教杯数学建模D题风电场运行状况分析及优化解题全过程文档及程序

2016年国赛高教杯数学建模 D题风电场运行状况分析及优化 风能是一种最具活力的可再生能源&#xff0c;风力发电是风能最主要的应用形式。我国某风电场已先后进行了一、二期建设&#xff0c;现有风机124台&#xff0c;总装机容量约20万千瓦。请建立数学模型&#xff0c;解决以下…

探索私有化聊天软件:即时通讯与音视频技术的结合

在数字化转型的浪潮中&#xff0c;企业对于高效、安全、定制化的通讯解决方案的需求日益迫切。鲸信&#xff0c;作为音视频通信技术的佼佼者&#xff0c;凭借其强大的即时通讯与音视频SDK&#xff08;软件开发工具包&#xff09;结合能力&#xff0c;为企业量身打造了私有化聊天…

MySQL Mail服务器集成:如何配置发送邮件?

MySQL Mail插件使用指南&#xff1f;怎么优化 MySQL发邮件性能&#xff1f; MySQL Mail服务器的集成&#xff0c;使得数据库可以直接触发邮件发送&#xff0c;极大地简化了应用架构。AokSend将详细介绍如何配置MySQL Mail服务器&#xff0c;以实现邮件发送功能。 MySQL Mail&…

【YashanDB知识库】如何配置jdbc驱动使getDatabaseProductName()返回Oracle

本文转自YashanDB官网&#xff0c;具体内容请见https://www.yashandb.com/newsinfo/7352676.html?templateId1718516 问题现象 某些三方件&#xff0c;例如 工作流引擎activiti&#xff0c;暂未适配yashandb&#xff0c;使用中会出现如下异常&#xff1a; 问题的风险及影响 …

【STM32】江科大STM32笔记汇总(已完结)

STM32江科大笔记汇总 STM32学习笔记课程简介(01)STM32简介(02)软件安装(03)新建工程(04)GPIO输出(05)LED闪烁& LED流水灯& 蜂鸣器(06)GPIO输入(07)按键控制LED 光敏传感器控制蜂鸣器(08)OLED调试工具(09)OLED显示屏(10)EXTI外部中断(11)对射式红外传感器计次 旋转编码器…

K8S服务发布

一 、服务发布方式对比 二者主要区别在于&#xff1a; 1、部署复杂性&#xff1a;传统的服务发布方式通常涉及手动配置 和管理服务器、网络设置、负载均衡等&#xff0c;过程相对复 杂且容易出错。相比之下&#xff0c;Kubernetes服务发布方式 通过使用容器编排和自动化部署工…

QT----Creater14.0,qt5.15无法启动调试,Launching GDB Debugger报红

问题描述 使用QT Creater 14.0 和qt5.15,无法启动调试也没有报错,加载debugger报红 相关文件都有 解决方案 尝试重装QT,更换版本5.15.2,下载到文件夹,shift鼠标右键打开powershell输入 .\qt-online-installer-windows-x64-4.8.0.exe --mirror http://mirrors.ustc.edu.cn…

解决fatal: unable to access ‘https://........git/‘: Recv failure: Operation time

目录 前言 解决方法一 解决方法二 解决方法三 解决方法四 总结 前言 在使用 Git 进行代码拉取时&#xff0c;可能会遇到连接超时的问题&#xff0c;特别是在某些网络环境下&#xff0c;例如公司网络或防火墙严格的环境中。这种情况下&#xff0c;Git 无法访问远程仓…

OpenHarmony(鸿蒙南向)——平台驱动指南【DAC】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 概述 功能简介 DAC&#xff08;Digital to Analog Converter&…

LLM - 使用 RAG (检索增强生成) 多路召回 实现 精准知识问答 教程

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/142629289 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 RAG (R…

windows下 Winobj.exe工具使用说明c++

1、winobj.exe工具下载地址 WinObj - Sysinternals | Microsoft Learn 2、接下来用winobj.exe查看全局互斥&#xff0c;先写一个小例子 #include <iostream> #include <stdlib.h> #include <tchar.h> #include <string> #include <windows.h>…