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

news2024/12/26 23:53:55

      🧸安清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;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", jobs='" + jobs + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }
}

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

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

<?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="CustomerMapper">
    <select id="QueryByNameAndJobs" parameterType="Customer" resultType="Customer">
        select * from customer
            where 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 configuration
        PUBLIC "-//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 {
    @Test
    public 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 mapper
        PUBLIC "-//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 {
    @Test
    public 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(),具体实现代码如下:

@Test
    public 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(),具体实现代码如下:

    @Test
    public 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(),具体实现代码如下:

    @Test
    public 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(),具体实现代码如下:

    @Test
    public 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.coloradmin.cn/o/2178041.html

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

相关文章

机器学习:opencv--背景建模

目录 一、背景建模是什么&#xff1f; 二、背景建模的目的 三、背景建模的方法及原理 四、代码实现 1.创建卷积核 2.创建混合高斯模型 3.处理图像 4.绘制人形轮廓 5.条件退出 一、背景建模是什么&#xff1f; 指在计算机视觉中&#xff0c;从视频序列中提取出静态背景…

深入工作流调度的内核

在大数据时代&#xff0c;工作流任务调度系统成为了数据处理和业务流程管理的核心组件&#xff0c;在大数据平台的构建和开发过程中尤为重要。随着数据量的激增和业务需求的多样化&#xff0c;合理的任务调度不仅能够提高资源利用率&#xff0c;还能保证业务流程的稳定和高效运…

Cannon-es.js之Distance Constrait物体约束详解

本文目录 前言最终效果1、Distance Constrait的基本属性和方法1.1 属性1.2 方法 2、Distance Constrait的约束详解2.1 前置代码准备2.2 效果 3、模拟生成小球撞击3.1 代码3.2 效果 前言 在Cannon-es.js中&#xff0c;DistanceConstraint&#xff08;距离约束&#xff09;是一种…

【华为HCIP实战课程三】动态路由OSPF的NBMA环境建立邻居及排错,网络工程师

一、NBMA环境下的OSPF邻居建立问题 上节我们介绍了NBMA环境下OSPF邻居建立需要手动指定邻居,因为NBMA环境是不支持广播/组播的 上一节AR1的配置: ospf 1 peer 10.1.1.4 //手动指定邻居的接口地址,而不是RID peer 10.1.1.5 area 0.0.0.0 手动指定OSPF邻居后抓包查看OSP…

Linux命令:块设备信息查看命令lsblk的具体介绍

目录 一.lsblk的介绍 二.基础用法 2.1基础命令和示意图 2.2详细说明 三.进阶用法 3.1列出指定的块设备信息 3.2查看设备完整路径 3.3强制以树形式输出信息 3.4其他参数 一.lsblk的介绍 lsblk是Linux系统中的一个命令行工具&#xff0c;用于列出所有可用的块设备&#…

基于单片机的可调式中文电子日历系统

** 文章目录 前言概要功能设计软件设计效果图 程序文章目录 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们…

RK3588主板PCB设计学习(六)

可以在其它层对过孔进行削盘处理&#xff0c; 可以看到&#xff0c;这里有些过孔用不上&#xff0c;在这一层进行了削盘处理&#xff1a; 对于这种电源层进行铺铜操作的时候&#xff0c;如果不进行削盘处理的话这些焊盘可能导致这个电源层面不完整&#xff0c;存在割裂的风险&a…

平安养老险肇庆中心支公司开展“2024年金融教育宣传月”活动

为加强消费者金融教育宣传&#xff0c;切实提升社会公众金融素养&#xff0c;有效防范化解金融风险&#xff0c;营造和谐健康金融环境&#xff0c;在肇庆金融监管分局指导下&#xff0c;平安养老险肇庆中心支公司开展金融教育宣传月暨反洗钱宣传月系列活动。 9月11日&#xff…

基于Springboot+Vue的高校教室资源管理系统的设计与实现(含源码+数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 这个系…

学习docker第二弹------基本命令[帮助启动类命令、镜像命令、容器命令]

docker目录 前言基本命令帮助启动类命令停止docker服务查看docker状态启动docker重启docker开机启动docker查看概要信息查看总体帮助文档查看命令帮助文档 镜像命令查看所有的镜像 -a查看镜像ID -q在仓库里面查找redis拉取镜像查看容器/镜像/数据卷所占内存删除一个镜像删除多个…

美图AI短片创作工具MOKI全面开放 支持生成配乐、细节修改

人工智能 - Ai工具集 - 集合全球ai人工智能软件的工具箱网站 美图公司近日宣布&#xff0c;其研发的AI短片创作工具MOKI已正式向所有用户开放。这款专注于AI短片创作的工具&#xff0c;提供了包括动画短片、网文短剧等多种类型视频内容的生成能力&#xff0c;致力于为用户带来…

Foo a30 = Foo(123);会调用哪些构造函数

一、解答 在您提供的代码中&#xff0c;表达式 Foo a30 Foo(123); 会直接调用 Foo 类中接受一个 int 类型参数的构造函数。这里是构造函数的调用过程&#xff1a; Foo(123) 创建了一个临时的 Foo 对象&#xff0c;使用的是接受 int 参数的构造函数。这个构造函数内部会执行 c…

6.数据结构与算法-线性表的链式表示和实现-单链表

链式存储结构 与链式存储有关的术语 单链表&#xff0c;双链表&#xff0c;循环链表 头指针&#xff0c;头节点&#xff0c;首元节点 有无头节点的区别 如何表示空表 设置头节点的好处 头节点的数据域内装什么 链表&#xff08;链式存储&#xff09;的特点 带头节点的单链表 单…

【中级通信工程师】综合能力:2024年真题回顾(附答案)

【零基础3天通关中级通信工程师】 综合能力&#xff1a;2024年真题回顾 本文是根据参加考试的回忆并且结合网上几版资料复原的2024年通信考试中级《综合能力》的真题考卷&#xff0c;旨在为广大考生提供复习和备考的参考&#xff0c;试卷大体和真题相符&#xff0c;部分选项回…

算法闭关修炼百题计划(一)

多看优秀的代码一定没有错&#xff0c;此篇博客属于个人学习记录 1.两数之和2.前k个高频元素3.只出现一次的数字4.数组的度5.最佳观光组合6.整数反转7.缺失的第一个正数8.字符串中最多数目的子序列9.k个一组翻转链表10.反转链表II11. 公司命名12.合并区间13.快速排序14.数字中的…

Windows Defender 强力删除工具 Defender Remover 下载

DefenderRemover.exe官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘123云盘为您提供DefenderRemover.exe最新版正式版官方版绿色版下载,DefenderRemover.exe安卓版手机版apk免费下载安装到手机,支持电脑端一键快捷安装https://www.123865.com/s/ajCgTd-79HEDefenderRemo…

文件传输工具 | 闪电藤 v2.5.5 绿色版

软件简介 闪电藤是一款基于LocalSend二次开发的局域网文件传输工具。它特别针对中国用户的使用习惯&#xff0c;对UI交互进行了重新设计&#xff0c;并在功能上进行了增强和删减。这款工具的特点包括极简无广告的界面&#xff0c;无需登录即可使用&#xff0c;能够自动连接同一…

一钉多用:自攻螺钉在家居与工业领域的广泛应用

自攻螺钉的结构要素有哪些重要特点&#xff1f; 自攻螺钉适用于非金属或软金属&#xff0c;不需要配合预先开好的孔和攻牙。自攻螺钉的尖头设计使其能够“自我攻入”材料中&#xff1b;而普通螺丝通常是平头&#xff0c;规格一致。自攻螺钉的关键在于&#xff0c;打孔时不需要进…

Java五子棋

目录 一&#xff1a;案例要求&#xff1a; 二&#xff1a;代码&#xff1a; 三&#xff1a;结果&#xff1a; 一&#xff1a;案例要求&#xff1a; 实现一个控制台下五子棋的程序。用一个二维数组模拟一个15*15路的五子棋棋盘&#xff0c;把每个元素赋值位“┼”可以画出棋…

猴子都看不懂的矩阵乘法——由向量乘矩阵到矩阵乘矩阵

矩阵乘法 仅为初学者的理解&#xff0c;不喜勿喷 矩阵&#xff0c;即为如下形式的结构&#xff1a; 0 1 1 1 1 0 1 0 1 \begin{matrix} 0&1&1\\ 1&1&0\\ 1&0&1\\ \end{matrix} 011​110​101​ 既然你准备仔细阅读这篇文章&#xff0c;那么相信你应…