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

目录

一、解决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.mzph.cn/news/10255.shtml

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

相关文章

【Spring Cloud Alibaba】Sentinel运行原理

文章目录 前言1、基本原理2、SphU.entry()2.1、StringResourceWrapper2.2、Entry 3、entry.exit()4、Context 前言 本文基于sentinel-1.8.0版本 Sentinel 是面向分布式服务架构的流量控制组件&#xff0c;主要以流量为切入点&#xff0c;从限流、流量整形、熔断降级、系统负载保…

ajax axios json

目录 一、ajax概述 1. 概念 2. 实现方式 &#xff08;1&#xff09;原生的JS实现方式&#xff08;了解&#xff09; &#xff08;2&#xff09; JQeury实现方式 二、axios 介绍 三、axios使用 1. axios 发送get/post请求 2. axios验证用户名称是否存在 四、json 1. …

设计模式——观察者模式

文章目录 1 概述2 实现3 总结 1 概述 观察者模式可以分为观察者和被观察者&#xff0c;观察者通过注册到一个被观察者中&#xff0c;也可视为订阅&#xff0c;当被观察者的数据发生改变时&#xff0c;会通知到观察者&#xff0c;观察者可以据此做出反应。 可以类比订阅报纸&am…

vue3+ts+elementui-plus二次封装弹框

一、弹框组件BaseDialog <template><div classmain><el-dialog v-model"visible" :title"title" :width"dialogWidth" :before-close"handleClose"><!-- 内容插槽 --><slot></slot><template…

【Docker】Consul的容器服务更新与发现

目录 一、Consul二、什么是服务注册与发现1.2什么是consul1.3consul提供的一些关键特性 二、Consul部署2.1环境配置2.2Consul服务器配置1. 建立 Consul 服务2. 查看集群信息3. 通过 http api 获取集群信息 2.3 registrator服务器配置1. 安装 Gliderlabs/Registrator2. 测试服务…

【数据挖掘】PCA/LDA/ICA:A成分分析算法比较

一、说明 在深入研究和比较算法之前&#xff0c;让我们独立回顾一下它们。请注意&#xff0c;本文的目的不是深入解释每种算法&#xff0c;而是比较它们的目标和结果。 如果您想了解更多关于PCA和ZCA之间的区别&#xff0c;请查看我之前基于numpy的帖子&#xff1a; PCA 美白与…

Leetcode-每日一题【114.二叉树展开为链表】

题目 给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。 展开后的单链表应该与二叉树 先序遍历 顺序相同。 示例…

JavaEE——Spring中存取Bean的注解

目录 一、存储Bean对象 1、定义 2、存储方式 &#xff08;1&#xff09;、类注解 【1】、Controller&#xff08;控制器存储&#xff09; 【2】、Service&#xff08;服务存储&#xff09; 【3】、Repository&#xff08;仓库存储&#xff09; 【4】、Component&#xf…

9个可用于图片转文本的最佳免费 OCR 软件

光学字符识别 (OCR) 软件可帮助将不可编辑的文档格式&#xff08;例如 PDF、图像或纸质文档&#xff09;转换为可编辑和可搜索的机器可读格式。 OCR 应用程序通常用于从 PDF 和图像中捕获文本&#xff0c;并将文本转换为可编辑格式&#xff0c;例如 Word、Excel 或纯文本文件。…

【LeetCode每日一题】——946.验证栈序列

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 栈 二【题目难度】 中等 三【题目编号】 946.验证栈序列 四【题目描述】 给定 pushed 和 p…

C++OpenCV(6):图像阈值操作

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 &#x1f506; OpenCV项目地址及源代码&#xff1a;点击这里 文章目录 图像阈值化 图像阈值化 阈值又叫临界值&#xff0c;是指一个效应能够产生的最低值或最高值。 例如我们选择的阈值为125&#xff0c;则…

智能网关实现混凝土搅拌机无人自动化

“以前的搅拌站生产时&#xff0c;是需要人工巡检的&#xff0c;运送物料和搅拌时产生的大量粉尘污染和噪音&#xff0c;让工人苦不堪言。但是如果有了物联网搅拌站监测系统智慧园区项目落地后&#xff0c;工人也不用去现场忍受噪音和粉尘了。” 行业痛点 传统模式下的混泥土…

机器学习实战11-基于K-means算法的文本聚类分析,生成文本聚类后的文件

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍机器学习实战11-基于K-means算法的文本聚类分析&#xff0c;生成文本聚类后的文件。文本聚类分析是NLP领域的一个核心任务&#xff0c;通过将相似的文本样本分组&#xff0c;可以帮助我们发现隐藏在文本数据中的模式和结…

力扣题库刷题笔记73--矩阵置零

1、题目如下&#xff1a; 2、个人Python代码实现 3、个人Python代码思路 a、声明2个空数组p、q&#xff0c;用于存放值为0的元素matrix[i][j]的下标 b、首先遍历二维数组matrix&#xff0c;找到值为0的元素matrix[i][j]&#xff0c;将下标i加入数组p&#xff0c;将下标j加入数…

高通WLAN框架学习(37)-- TDLS(Tunneled Direct Link Setup)通道直接链路建立

一 TDLS概述 隧道直连设置(TDLS)基于IEEE 802.11z-2010IEEE标准802.11z标准(无线局域网介质访问控制(MAC)和物理层(PHY)规范。 TDLS允许与同一AP关联的设备之间建立直接链路。Wi-Fi Direct允许设备之间直接连接,而不需要AP。Wi-Fi联盟认证可用于IEEE 802.11a和802.11g设备的T…

如何创建vue2,vue3项目

前提需安装node.js和Vue CLI node.js:https://nodejs.org/zh-cn Vue CLI&#xff1a; npm install -g vue/cli 如何创建一个vue2项目 &#xff08;1&#xff09; 使用cmd终端直接创建 进入到vue项目所创建的目录里&#xff08;我是直接创建在桌面上&#xff09; 选择vue2 …

入局元宇宙,所谓的无限可能到底在哪里?

最近的热点新闻表明&#xff0c;人们似乎认为元宇宙已经走向“死亡”。但实际上&#xff0c;市场应该重新定义对元宇宙的看法&#xff0c;以及正视它最大的机会所在——游戏领域。 1937年5月6日&#xff0c;一架名为兴登堡号的巨大氢能齐柏林飞艇飞临新泽西州曼彻斯特镇上空&a…

Jmeter+MySQL链接+JDBC Connection配置元件+使用

参考大大的博客学习&#xff1a;怎么用JMeter操作MySQL数据库&#xff1f;看完秒懂&#xff01;_jmeter mysql_程序员馨馨的博客-CSDN博客 注&#xff1a;里面所有没打码的都是假数据&#xff0c;麻烦大家自行修改正确的信息。 一、背景 需要取数据库中的值&#xff0c;作为…

Toyota Programming Contest 2023#4(AtCoder Beginner Contest 311)(A-G)

Contest Duration: 2023-07-22(Sat) 20:00 - 2023-07-22(Sat) 21:40 (local time) (100 minutes) 头文件和宏 #include<iostream> #include<string> #include<vector> using namespace std; #define int long long #define fer(i,a,b) for(int ia;i<b;i…

【运维】DevOps全流程笔记(未完成)

运维笔记 DevOps基本流程Code阶段工具&#xff08;gitlab安装&#xff09;Build阶段工具&#xff08;Maven安装&#xff09;Integrate阶段工具JenkinsJenkins介绍Jenkins安装Jenkins入门配置 CI/CD操作集成Sonar Qube集成HarborJenkins流水线Kubernetes编排工具 DevOps全流程笔…