【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.rhkb.cn/news/435178.html

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

相关文章

端侧Agent系列 | 端侧AI Agent任务拆解大师如何助力AI手机?(详解版)

引言 简介 Octo-planner 规划和执行Agent框架 规划数据集 基准设计 实验设计 结果 全量微调与LoRA 多LoRA训练与合并 不同基础模型的全量微调 不同数据集大小的全量微调 总结 实战 英文 中文示例1&#xff1a; 中文示例2&#xff1a; 0. 引言 人生到处知何似…

【有啥问啥】具身智能(Embodied AI):人工智能的新前沿

具身智能&#xff08;Embodied AI&#xff09;&#xff1a;人工智能的新前沿 引言 在人工智能&#xff08;AI&#xff09;的进程中&#xff0c;具身智能&#xff08;Embodied AI&#xff09;正逐渐成为研究与应用的焦点。具身智能不仅关注于机器的计算能力&#xff0c;更强调…

排序算法的分析和应用

自己设计一个长度不小于10的乱序数组&#xff0c;用希尔排序&#xff0c;自己设定希尔排序参数 画出每一轮希尔排序的状态 自己设计一个长度不小于10的乱序数组&#xff0c;用堆排序&#xff0c;最终要生成升序数组&#xff0c;画出建堆后的状态 画出每一轮堆排序的状态 自…

【C++并发入门】摄像头帧率计算和多线程相机读取(上):并发基础概念和代码实现

前言 高帧率摄像头往往应用在很多opencv项目中&#xff0c;今天就来通过简单计算摄像头帧率&#xff0c;抛出一个单线程读取摄像头会遇到的问题&#xff0c;同时提出一种解决方案&#xff0c;使用多线程对摄像头进行读取。同时本文介绍了线程入门的基础知识&#xff0c;讲解了…

【OS】计算机系统概述|操作系统基本概念|并发|并行|虚拟异步

✨ Blog’s 主页: 白乐天_ξ( ✿&#xff1e;◡❛) &#x1f308; 个人Motto&#xff1a;他强任他强&#xff0c;清风拂山冈&#xff01; &#x1f525; 所属专栏&#xff1a;C深入学习笔记 &#x1f4ab; 欢迎来到我的学习笔记&#xff01; 前言 一、操作系统的概念 操作系统…

如何使用ssm实现基于Java的高校物业工程报修系统

TOC ssm736基于Java的高校物业工程报修系统jsp 绪论 1.1研究背景与意义 信息化管理模式是将行业中的工作流程由人工服务&#xff0c;逐渐转换为使用计算机技术的信息化管理服务。这种管理模式发展迅速&#xff0c;使用起来非常简单容易&#xff0c;用户甚至不用掌握相关的专…

2. 将GitHub上的开源项目导入(clone)到(Linux)服务器上——深度学习·科研实践·从0到1

目录 1. 在github上搜项目 (以OpenOcc为例&#xff09; 2. 转移到码云Gitee上 3. 进入Linux服务器终端 (jupyter lab) 4. 常用Linux命令 5. 进入对应文件夹中导入项目(代码) 注意&#xff1a;系统盘和数据盘 1. 在github上搜项目 (以OpenOcc为例&#xff09; 把链接复制下…

llamafactory0.9.0微调qwen2.5

llama_factory微调QWen1.5_llama factory qwen-CSDN博客文章浏览阅读2.9k次,点赞36次,收藏10次。本文介绍了如何使用LLaMA-Factory微调Qwen1.5模型,包括1.8B和0.5B版本的训练细节。在数据、训练、LORA融合及推理等方面进行了探讨,同时也分享了微调后模型在不同任务上的表现…

Linux快速安装ClickHouse(附官方文档)

在线安装 1.安装yum-utils yum-utils是一个与 yum 集成的实用程序集合&#xff0c;可以通过多种方式扩展其本机功能 yum install -y yum-utils 2.增加ClickHouse官方镜像源 yum-config-manager --add-repo https://packages.clickhouse.com/rpm/clickhouse.repo 3.安装Cl…

【JavaEE初阶】网络原理

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 ⽹络互连 IP地址 端口号 协议 协议分层 优势 TCP/IP 五层网络模型 数据在网络通信中的整体流程 封装和分用 封装 分用 ⽹络互连 随着时代的发展&#xff0c;越来越需…

828华为云征文 | 云服务器Flexus X实例:向量数据库 pgvector 部署,实现向量检索

目录 一、什么是向量数据库 pgvector &#xff1f; 二、pgvector 部署 2.1 安装 Docker 2.2 拉取镜像 2.3 添加规则 三、pgvector 运行 3.1 运行 pgvector 3.2 连接 pgvector 3.3 pgvector 常见操作 四、总结 本篇文章通过 云服务器Flexus X实例 部署向量数据库 pgve…

第十四章:html和css做一个心在跳动,为你而动的表白动画

💖 让心跳加速,传递爱意 💖 在这个特别的时刻,让爱在跳动中绽放!🌟 无论是初次相遇的心动,还是陪伴多年的默契,我们的心总在为彼此跳动。就像这颗炙热的爱心,随着每一次的跳动,传递着满满的温暖与期待。 在这个浪漫的季节,让我们一同感受爱的律动!无论你是在…

手搓 HTTP服务器 手把手带你实现高并发HTTP服务器 C++ HTTP服务器 服务器项目实战 高性能服务器实战 服务器项目 服务器

手搓 HTTP服务器 高并发HTTP服务器 C HTTP服务器 1、什么是socket Socket是一种用于网络通信的编程接口&#xff0c;允许不同计算机之间通过网络发送和接收数据。它在客户端和服务器之间创建连接&#xff0c;支持多种协议&#xff0c;如TCP和UDP。2、实现socket 通讯 1、soc…

Milvus - 架构设计详解

Milvus 是一个专为在大规模密集向量数据集上进行相似性搜索而设计的开源向量数据库系统。其架构建立在流行的向量搜索库之上&#xff0c;如 Faiss、HNSW、DiskANN 和 SCANN&#xff0c;能够处理数百万、数十亿甚至数万亿的向量数据。为了全面了解 Milvus 架构&#xff0c;我们首…

苏州 数字化科技展厅展馆-「世岩科技」一站式服务商

数字化科技展厅展馆设计施工是一个综合性强、技术要求高的项目&#xff0c;涉及到众多方面的要点。以下是对数字化科技展厅展馆设计施工要点的详细分析&#xff1a; 一、明确目标与定位 在设计之初&#xff0c;必须明确展厅的目标和定位。这包括确定展厅的主题、目标受众、展…

实用SQL小总结

WHERE 条件 column 为纯英文字符 或 不包含任何字符 语法&#xff1a; SELECT * FROM your_table WHERE REGEXP(your_column,^[A-Za-z]$); SELECT * FROM your_table WHERE NOT REGEXP(your_column,^[A-Za-z]$);例&#xff1a; SELECT DISTINCT t.pldlibho FROM kibb_pldlyw…

Naive UI 选择器 Select 的:render-label 怎么使用(Vue3 + TS)

项目场景&#xff1a; 在Naive UI 的 选择器 Select组件中 &#xff0c;如何实现下面的效果 &#xff0c;在下拉列表中&#xff0c;左边展示色块&#xff0c;右边展示文字。 Naive UI 的官网中提到过这个实现方法&#xff0c;有一个render-label的api&#xff0c;即&#xff…

数据库操作:数据类型

0. 铺垫 1.数值类型 注&#xff1a;此图的最大值都要减1&#xff1b;因为我的错误&#xff0c;后面会改正&#xff1b; 1.0、tinyint 类型大小——1字节 create table tt1(num tinyint); insert into tt1 values(1); insert into tt1 values(128); -- 越界插入&#xff0c;…

【Android】 IconFont的使用

SVG 的特点&#xff1a; 矢量图形&#xff1a;SVG 使用基于路径的矢量图形&#xff0c;这意味着图形可以无限放大而不失真&#xff0c;非常适合需要多种分辨率的应用。 可伸缩性&#xff1a;SVG 文件的大小通常比位图小&#xff0c;这使得它们在网页上加载更快。 编辑和创作&…

Text-to-SQL方法研究

有关Text-to-SQL实现细节&#xff0c;可以查阅我的另一篇文章text-to-sql将自然语言转换为数据库查询语句 1、面临的挑战 自然语言问题往往包含复杂的语言结构,如嵌套语句、倒装句和省略等,很难准确映射到SQL查询上。此外,自然语言本身就存在歧义,一个问题可能有多种解读。消除…