【MyBatis 学习三】子段不一致问题 多表查询 动态SQL

news2024/11/27 22:25:56

目录

一、解决Java实体类属性与数据库表字段不一致问题

🌷现象1:显示字段不对应:使用ResultType查询结果为null;

🌷解决办法:字段不对应:使用ResultMap解决。

二、数据库的多表查询

🌷方式1:使用对象user 

🌷方式2:直接写具体的属性

三、动态SQL的使用

🌷1、if标签:单个参数不确定

🌷2、trim标签:多个参数不确定,搭配if标签一起使用

🌷3、where标签:搭配if标签

方式1:使用where关键字(注意不是where标签)

方式2:使用标签

🌷4、set标签:搭配if标签

🌷5、foreach标签:用于批量操作,搭配if\where标签

🍉个人小结


一、解决Java实体类属性与数据库表字段不一致问题

        在对数据进行增删改查的时候,如果是增,删,改一般会返回受影响的行数,所以在mapper.xml文件中可以不设置返回的类型;但是对于查询,无论查询什么内容,都要设置返回的数据类型。如下:

查询:

 增加、删除和修改:一般可以不设置返回类型:

 所以对于<select>查询标签来说,至少需要两个属性

(1)i属性:用于标识实现接口中的哪个方法;

(2)结果映射属性:有两种实现标签:<resultType>和<resultMap>

         其中,在前一节我们定义用户实体类的时候,强调了当时的属性名要与数据库中表的字段名一致,就可以使用<resultType>了。但是在实际开发中,Java中的实体类属性一般是小驼峰命名,数据库中的字段属性是字母小写并用下划线分隔,两者之间的名称可能不一致,那么此时就要用到<resultMap>了。

🌷现象1:显示字段不对应:使用ResultType查询结果为null;

xml文件 

 结果:

🌷解决办法:字段不对应:使用ResultMap解决。

UserMapper.xml文件

<resultMap id="BaseMap1" type="demo3.model.User">
        <id property="id" column="id"></id>
        <result property="name" column="username"></result>
        <result property="pwd" column="password"></result>
        <result property="photo" column="photo"></result>
        <result property="createTime" column="createTime"></result>
        <result property="updateTime" column="updateTime"></result>
        <result property="state" column="state"></result>
    </resultMap>
    <select id="queryAllByMap" resultMap="BaseMap1">
        select * from userinfo
    </select>

结果: 

注意点:       

         一个xml文件中可以有多个resultMap,只要Id不同就行。(我们这里是所有的字段都写了)实际没写的字段,会按照默认的规则来帮助我们映射:当数据库字段和Java属性字段一直的话,就会自动映射。通常情况下,如果我们写了ResultMap,不论是否一致,都将属性写全。


二、数据库的多表查询

有两张表:

 数据库中的左连接操作:根据文章表中的用户id查找对应的用户表的用户信息,写法如下:我们现在就实现这个功能:

🌷方式1:使用对象user 

创建两个类:User类和Article类

注意点1:这里设置文章表的属性的时候,设置一个user对象。

 UserMapper与ArticleMapper

xml文件

注意点2:在ArticleMapper.xml文件中设置user的时候,要用association引入UserMapper的ResultMap的路径:路径名是UserMapper的namespace名+ResultMap的id名称。

测试类:

 测试结果:

注意点3:可以看到在文章表中查询出来的结果,其中的用户信息是一个user对象来表示的。

🌷方式2:直接写具体的属性

注意1:这里的文章类:我们就不定义user对象了,而是要查询用户的Id和用户名,我们就将这两个字段定义出来。

注意点2:xml文件中也是直接通过resutMap的result定义出用户的Id和用户名,不用再引入UserMapper.xml文件中的ResultMap了。

结果: 

注意点3:可以看到最终查询的结果也是具体的用户Id和用户名信息,而不是方式1的整个user对象。


三、动态SQL的使用

动态SQL:根据输入参数的不同,动态的拼接SQL,从而完成不同条件下的SQL拼接。

        比如在实际场景下,有时候我们进行注册,有的字段是必填的,有的又不是必填的,如果在注册用户的时候有不确定的字段传入,那么怎么实现呢?

🌷1、if标签:单个参数不确定

 <insert id="insertByIf">
        insert into articleInfo ( title,content,uid      
        <if test="state!=null">
            ,state
         </if>
        )
        values ( #{title},#{content},#{uid}        
        <if test="state!=null">
            ,#{state}
        </if>
        )
    </insert>

(1)用法

 测试结果1:当输入state状态: 

 测试情况2:不输入state

注意:if标签里面的属性是Java对象的属性字段state,而不是数据库表中的字段。而insert中的sql语句的字段是数据库表中的字段,注意区分~

(2)存在问题

当我多个参数都不确定的时候,写成id标签的形式,会导致逗号放在哪里都存在问题。

        如果统一将逗号放在字段前面,当第一个字段为null的时候,整个SQL最前面就会多一个逗号;如果统一将逗号放在字段后面,当最后一个字段为null的时候,整个SQL最后面就会多一个逗号,所以这个时候我们就要用<trim>标签结合<if>标签,对多个字段都采取动态⽣成的⽅式了。

🌷2、trim标签:多个参数不确定,搭配if标签一起使用

<trim>标签中有如下属性:

  • prefix:表示整个语句块,以prefix的值作为前缀:表示从(开始
  • suffix:表示整个语句块,以suffix的值作为后缀:表示从   )结束
  • prefixOverrides:表示整个语句块要去除掉的前缀:表示去掉左边的逗号
  • suffixOverrides:表示整个语句块要去除掉的后缀:表示去掉右边的逗号
 <insert id="insertByIf">
        insert into articleInfo
        <trim prefix="(" suffix=")" prefixOverrides="," suffixOverrides=",">
            <if test="title!=null">
                title,
            </if>
            <if test="content!=null">
                content,
            </if>
            <if test="uid!=null">
                uid,
            </if>
            <if test="state!=null">
                state
             </if>

        </trim>
        values
        <trim prefix="(" suffix=")" prefixOverrides="," suffixOverrides=",">
            <if test="title!=null">
                #{title},
            </if>
            <if test="content!=null">
                #{content},
            </if>
            <if test="uid!=null">
                #{uid},
            </if>
            <if test="state!=null">
                #{state}
            </if>
        </trim>
    </insert>

在以上 sql 动态解析时,会将第⼀个 <trim> 部分做如下处理:
(1)基于 prefix 配置,开始部分加上 (
(2)基于 suffix 配置,结束部分加上 )
(3)多个 <if>组织的语句都以 , 结尾,在最后拼接好的字符串还会以 , 结尾,会基于 suffixO
verrides 配置去掉最后⼀个 ,
(4)注意 <if test=“state!= null”> 中的 state是传⼊对象的属性;

测试:当不传入state的时候:

🌷3、where标签:搭配if标签

方式1:使用where关键字(注意不是where标签)

当uid为null的时候: 

当state为null的时候:

当uid和state为null的时候:

方式2:使用<where>标签

 当uid为null的时候: 

当state为null的时候

 当两个都为null的时候:

 从上述案例中可以看出where标签的作用:

(1)生成where关键字;

(2)去掉多余的and;

(3)如果没有where条件,就不会生成where关键字

🌷4、set标签:搭配if标签

当只设置uid值的时候,测试通过(同样其他情况也是测试通过的。)

set作用:

(1)set标签生成set关键字;

(2)去除最后一个逗号。 

🌷5、foreach标签:用于批量操作,搭配if\where标签

批量操作:插入、删除、更新等。演示批量删除:

  • collection:绑定⽅法参数中的集合,如 List,Set,Map或数组对象;
  • item:遍历时的每⼀个对象
  • open:语句块开头的字符串
  • close:语句块结束的字符串
  • separator:每次遍历之间间隔的字符串。

 注意:collection中除了可以写Llist,还可以写参数名称,此时对参数进行重命名:

🍉个人小结:

1、字段名称和程序中的属性名不同的情况,可使⽤ resultMap 配置映射。

2、多表查询:文章表中有用户Id和用户名,要通过文章表查询用户信息:有两种方式:

(1)在文章实体类定义属性为user,则文章表的xml文件中要通过association引入用户user的ResultMap的地址;

(2)直接在文章的实体类中定义属性用户Id和用户名,此时文章表中的xml文件通过resultMap引入这两个属性。

3、动态SQL:

(1)<if>标签是基础,后面的<trim>标签、<where>、<set>、<foreach>标签都是结合if标签使用的。

(2)当只有单个参数不确定的时候,使用If标签;

(3)当多个参数不确定,要trim标签;

(4)条件不确定的时候用where标签:也可以用where关键字加一个条件1=1;

(5)set标签设置 不确定的属性;

(6)foreach标签批量处理数据:插入、删除修改等。collection中传入list等;当对接口方法中的参数重命名后,collection也可以使用参数的名称。😁


 

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

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

相关文章

【【51单片机的红外遥控】】

红外遥控&#xff0c;完全把控 红外遥控 利用红外光进行通信的设备&#xff0c;由红外LED将调制后的信号发出&#xff0c;再由专门的红外接收头进行解调输出 通信方式&#xff1a;单工 异步 红外LED波长&#xff1a;940nm 通信协议标准&#xff1a;NEC标准 用那种一体化红红外…

面试总结-Redis篇章(八)——Redis分布式锁

JAVA 面试总结-Redis分布式锁 模拟抢券场景 通过下面方法添加Synchronized锁来防止上述情况&#xff0c;如果上面是单体服务没有问题&#xff0c;但是如果项目是集群部署&#xff0c;会出现下面的问题&#xff0c;因为Synchronized是属于本地的锁端口8080和8081同时访问&#x…

抽象工厂模式——产品族的创建

1、简介 1.1、简介 抽象工厂模式为创建一组对象提供了一种解决方案。与工厂方法模式相比&#xff0c;抽象工厂模式中的具体工厂不只是创建一种产品&#xff0c;它负责创建一族产品 1.2、定义 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;&#xff1a;提供…

【MySQL】SQL优化(九)

&#x1f697;MySQL学习第九站~ &#x1f6a9;本文已收录至专栏&#xff1a;MySQL通关路 ❤️文末附全文思维导图&#xff0c;感谢各位点赞收藏支持~ 一.插入数据 (1) 小规模数据 如果我们需要一次性往数据库表中插入多条记录: -- 例如我们需要插入大量数据 insert into t…

3.安装kubesphere

1.本地存储动态 PVC # 在所有节点安装 iSCSI 协议客户端&#xff08;OpenEBS 需要该协议提供存储支持&#xff09; yum install iscsi-initiator-utils -y # 设置开机启动 systemctl enable --now iscsid # 启动服务 systemctl start iscsid # 查看服务状态 systemctl status …

第三大的数

414、第三大的数 class Solution {public int thirdMax(int[] nums) {Arrays.sort(nums);int tempnums[0];int ansnums[0];int count 0;// if(nums.length<3){// return nums[nums.length-1];// }// else {for(int inums.length-1;i>0;i--){if (nums[i]>nums[i…

如何提高自己的软件测试水平之bug定位

同学们在面试投简历的时候会经常看到人家公司JD上写的要求之一&#xff0c;如下&#xff1a; 这句话大家不要以为随便写写的&#xff0c;在我工作的十几年过程中起码见过10个以上试用期没过的公司新人&#xff0c;公司在衡量一个测试工程师是否专业的标准之一就是&#xff1a;…

常用的数据结构 JAVA

目录 1、线性表2、栈&#xff1a;3、队列&#xff1a; 1、线性表 List<Object> narnat new ArrayList<>();ArrayList&#xff1a;动态数组 1、可以嵌套使用 2、add(x)添加元素x&#xff0c;remove(index)删除某个位置的元素 3、注意list是指向性的&#xff0c…

appium2.x 最新安装教程来了!不用再装 appium desktop 了!

前言 新的appium已经舍弃了appium-server&#xff0c;重新回归到只有命令行安装和启动appium服务。 本文是基于最新的appium2.x的安装教程。正想学习使用appium的不要错过。 1、安装最新版本的node.js 下载地址&#xff1a;https://nodejs.org/en&#xff0c;一路安装完成即…

SpringCloud学习笔记(五)ElasticSearch介绍

一、什么是ElasticSearch ElasticSearch是一款开源搜索引擎&#xff0c;可以帮助我们从海量数据中快速找到需要的内容ElasticSearch结合kibana、Logstash、Beats&#xff0c;也就是elastic stack&#xff08;ELK&#xff09;。被广泛应用在日志数据分析、实时监控等领域Elasti…

JAVA 正则表达式(heima)

JAVA 正则表达式&#xff08;heima&#xff09; public class RegexDemo01 {/** 正则表达式介绍&#xff1a;本质来说就是一个字符串&#xff0c;字符串中可以指定规则&#xff0c;来对其他字符串进行校验。* public boolean matches(String regex):根据传入的正则表达式&#…

Jmap-JVM(十六)

上篇文章说了ZGC是jdk11加入的&#xff0c;他是未来jvm垃圾收集器的奠定者&#xff0c;满足TB级别内存处理&#xff0c;STW时间保持在10ms以下。 Jmap 我们可以先通过jmap -histo 进程ip 来查看&#xff0c;但是这样看不太清晰&#xff0c;我们可以用这行命令生成一个文件&…

Vue中TodoList案例_动画

MyItem.vue : 主要是引入了import animate.css样式库&#xff0c;animate.css样式库配置见上一篇文章animate.css样式库&#xff0c;然后再li标签外套了transition标签&#xff0c;引用了name里面的名称是animate.css拿过来的&#xff0c;绑定了enter-active-class和leave-act…

前端实现导出excel表格

需求&#xff1a;实现勾选行导出为表格 一、安装插件 npm install --save file-saver xlsx运行项目报如下警告的话 运行npm install xlsx0.16.0 --save 来降低版本号&#xff08;最初我安装的版本号是0.18.16的版本&#xff09;再次运行项目就不会报如下警告了 二、新建一个ex…

嵌入式开发:单片机嵌入式Linux学习路径

SOC&#xff08;System on a Chip&#xff09;的本质区别在于架构和功能。低端SOC如基于Cortex-M架构的芯片&#xff0c;如STM32和NXP LPC1xxx系列&#xff0c;不具备MMU&#xff08;Memory Management Unit&#xff09;&#xff0c;适用于轻量级实时操作系统如uCOS和FreeRTOS。…

SOC FPGA之HPS模型设计(一)

目录 一、建立HPS硬件系统模型 1.1 GHRD 1.2 从0开始搭建HPS 1.2.1 FPGA Interfaces 1.2.1.1 General 1.2.1.2 AXI Bridge 1.2.1.3 FPGA-to-HPS SDRAM Interface 1.2.1.4 DMA Peripheral Request 1.2.1.5 Interrupts 1.2.1.6 EMAC ptp interface 1.2.2 Peripheral P…

PostMan+Jmeter工具介绍及安装

目录 一、PostMan介绍​编辑 二、下载安装 三、Postman与Jmeter的区别 一、开发语言区别&#xff1a; 二、使用范围区别&#xff1a; 三、使用区别&#xff1a; 四、Jmeter安装 附一个详细的Jmeter按照新手使用教程&#xff0c;感谢作者&#xff0c;亲测有效。 五、Jme…

Linux:Linux的发展史和作用有哪些?

文章目录 Linux是什么&#xff1f;Linux的开源特征为什么要学习Linux&#xff1f;Linux的应用场景有哪些&#xff1f; Linux是什么&#xff1f; 简单来说&#xff0c;Linux就是操作系统&#xff0c;它和Windows等软件一样&#xff0c;都只是操作系统&#xff0c;并无区别 Linu…

linux查看系统版本、内存、CPU等信息

一、查看linux内核版本信息&#xff08;两种方法&#xff09; 1. cat /proc/version linux查看当前操作系统内核版本信息 2. uname -a linux查看当前操作系统内核版本信息 二、查看linux系统版本信息&#xff08;3种方法&#xff09; 1. lsb_release -a 可列出所有版本…

链表踏歌:独具慧眼,雕琢重复元素藏身匿迹

本篇博客会讲解力扣“83. 删除排序链表中的重复元素”的解题思路&#xff0c;这是题目链接。 由于链表是排好序的&#xff0c;我们可以通过遍历一次链表的方式&#xff0c;删除所有重复的结点。具体来说&#xff0c; 如果链表为空&#xff0c;则不需要删除&#xff0c;直接返回…