当前位置: 首页 > news >正文

MyBatis:关联查询

MyBatis

  • 前言
  • 关联查询
      • 懒加载
      • 对象为集合时的关联查询

在这里插入图片描述

前言

MyBatis:配置文件 文章中,最后介绍了可以使用 select 标签的 resultMap 属性实现关联查询,下面简单示例

关联查询

首先,先创建 association_role 和 association_user 两张数据表,并建立关联关系
表结构如图:
在这里插入图片描述
表信息如图:
在这里插入图片描述

在创建 association_user 表时需要添加 association_role 表的关联字段( role_id )
表结构如图:
在这里插入图片描述
表信息如图:
在这里插入图片描述

接着,创建与两张数据表一一映射的实体类 AssociationRole 和 AssociationUser

// AssociationRole
package cn.edu.MyBatisDemo.model;public class AssociationRole {private int id;private String role;public AssociationRole() {super();}public AssociationRole(int id, String role) {this.id = id;this.role = role;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getRole() {return role;}public void setRole(String role) {this.role = role;}@Overridepublic String toString() {return "AssociationRole{" +"id=" + id +", role='" + role + '\'' +'}';}
}
// AssociationUser
package cn.edu.MyBatisDemo.model;public class AssociationUser {private int id;private String name;//添加 AssociationRole 属性private AssociationRole role; // AssociationRole -- 1:m -- AssociationUser (一对多关系)public AssociationUser(int id, String name, AssociationRole role) {this.id = id;this.name = name;this.role = role;}public AssociationUser() {super();}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public AssociationRole getRole() {return role;}public void setRole(AssociationRole role) {this.role = role;}@Overridepublic String toString() {return "AssociationUser{" +"id=" + id +", name='" + name + '\'' +", role=" + role +'}';}
}

然后,创建一个接口 AssociationUserMap ,声明获取指定用户信息的方法。同时,创建映射文件 AssociationUserMap.xml 实现接口方法

// 接口 AssociationUserMap
package cn.edu.MyBatisDemo.mapper;import cn.edu.MyBatisDemo.model.AssociationUser;public interface AssociationUserMap {public AssociationUser selectUserById(int id); // 获取指定用户的信息
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- 映射文件 AssociationUserMap.xml -->
<mapper namespace="cn.edu.MyBatisDemo.mapper.AssociationUserMap"><select id="selectUserById" resultMap="associationUser">SELECT user.id,user.name,user.role_id,role.roleFROM association_user USER,`association_role` roleWHERE user.role_id=role.id AND user.id=#{id}</select><!-- id 设置别名;type 指定类 --><resultMap id="associationUser" type="cn.edu.MyBatisDemo.model.AssociationUser" ><!-- 字段名对应的属性名 --><id column="id" property="id" /><result column="name" property="name" /><!-- 映射关联对象的属性 --><result column="role_id" property="role.id" /><result column="role" property="role.role" /></resultMap>
</mapper>

最后,测试结果

package cn.edu.MyBatisDemo.test;import cn.edu.MyBatisDemo.mapper.AssociationUserMap;
import cn.edu.MyBatisDemo.model.AssociationUser;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;public class AssociationTest {@Testpublic void test() throws IOException {//1.根据配置文件创建数据库连接会话的工厂类InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");//获取工厂类SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2.通过工厂类获取数据库连接的会话SqlSession sqlSession = sqlSessionFactory.openSession();//3.通过 sqlSession 操作数据库try {AssociationUserMap userMap = sqlSession.getMapper(AssociationUserMap.class);//获取所有用户AssociationUser user = userMap.selectUserById(20230829);System.out.println(user);sqlSession.commit();} finally {sqlSession.close();}}
}

结果如图:
在这里插入图片描述

懒加载

懒加载( Lazy Loading ),是在使用所需数据时才进行加载,而不是直接加载所有关联数据。这有利于提高查询性能和减少资源消耗。当一个实体类中包含关联对象(如一对多、多对多关系)时,使用懒加载可以避免在查询主对象时立即加载所有关联对象的数据,而是等到真正需要访问关联对象时才进行加载。

简单示例:
在上面案例的基础上,先通过使用 association 标签实现分步关联查询,再进行配置懒加载

首先,再创建一个接口 AssociationRoleMap ,声明获取指定用户信息的方法。同时,创建映射文件 AssociationRoleMap.xml 实现接口方法

package cn.edu.MyBatisDemo.mapper;import cn.edu.MyBatisDemo.model.AssociationRole;public interface AssociationRoleMap {public AssociationRole selectRoleById(int id); // 获取指定用户的信息
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.edu.MyBatisDemo.mapper.AssociationRoleMap"><select id="selectRoleById" resultType="associationRole">SELECT `id`,`role` FROM `association_role` WHERE `id`=#{id}</select>
</mapper>

接着,在映射文件 AssociationUserMap.xml 中,使用 association 标签实现关联查询。同时,修改 select 标签上的 SQL 语句

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.edu.MyBatisDemo.mapper.AssociationUserMap"><select id="selectUserById" resultMap="associationUser"><!-- 对比:分步关联查询的 SQL 语句相对简单些 -->SELECT `id`,`name`,`role_id` FROM `association_user` WHERE `id`=#{id}</select><!-- id 设置别名;type 指定类 --><resultMap id="associationUser" type="cn.edu.MyBatisDemo.model.AssociationUser" ><!-- 字段名对应的属性名 --><id column="id" property="id" /><result column="name" property="name" /><!-- 映射关联对象的属性 --><!-- <result column="role_id" property="role.id" /> --><!-- <result column="role" property="role.role" /> --><!-- 也可以使用子标签 association 实现关联查询 --><!-- property = 添加 AssociationRole 属性 role ;select = 关联对象映射文件中的方法 id ;column = 外键 --><association property="role" select="cn.edu.MyBatisDemo.mapper.AssociationRoleMap.selectRoleById" column="role_id" ></association></resultMap>
</mapper>

然后,在 pom.xml 配置文件中添加依赖包。同时,在 resources 目录下创建 log4j.properties 资源文件。目的是生成日志文件,方便观察理解

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.16</version>
</dependency>
#日志级别,分为八个级别( Off-关闭日志记录 > Fatal-严重错误 > Error-错误 > Warn-警告 > Info-运行信息 > Debug-调试 > Trace-低级信息 > All-所有日志记录)
#日志级别越高,过滤的信息越多#配置根节点
log4j.rootLogger=Debug,stdout,D
#配置控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.Threshold=Error
##输出格式(%d %p [%1] %m %n——日期时间 类 路径 信息 换行)
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%l] %m %n#配置文件输出
log4j.appender.D=org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.Append=true
log4j.appender.D.File=./log4j.log
log4j.appender.D.Threshold=Debug
#输出格式
log4j.appender.D.layout=org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern=%d %p [%l] %m %n

随之,在 resources 目录下的 mybatis.xml 全局配置文件中进行配置懒加载

<!-- 懒加载配置 -->
<settings><setting name="LazyLoadingEnabled" value="true"/><setting name="aggressiveLazyLoading" value="false"/>
</settings>

最后,测试结果
1.只获取 association_user 中的 name 属性(只加载所需要的数据,其他数据不加载)
在这里插入图片描述
查看日志,结果如图:
在这里插入图片描述

2.分步关联查询(加载所有关联数据)
在这里插入图片描述
查看日志,结果如图:
在这里插入图片描述

对象为集合时的关联查询

当关联查询的对象为集合时,与上面案例的主要区别为使用的是 collection 标签,而不是 association 标签。

简单示例:
首先,在实体类 AssociationRole 中添加 users 属性
在这里插入图片描述

接着,分别在接口 AssociationUserMap 和 AssociationRoleMap 中添加相应的方法
在这里插入图片描述
在这里插入图片描述

然后,分别在映射文件 AssociationUserMap.xml 和 AssociationRoleMap.xml 中实现相应的方法。同时在 AssociationRoleMap.xml 配置关联映射
在这里插入图片描述
在这里插入图片描述

最后,测试结果
结果如图:
在这里插入图片描述

相关文章:

MyBatis:关联查询

MyBatis 前言关联查询附懒加载对象为集合时的关联查询 前言 在 MyBatis&#xff1a;配置文件 文章中&#xff0c;最后介绍了可以使用 select 标签的 resultMap 属性实现关联查询&#xff0c;下面简单示例 关联查询 首先&#xff0c;先创建 association_role 和 association_…...

第十二章 控制值的转换

文章目录 第十二章 控制值的转换介绍处理特殊 XML 字符文字和 SOAP 编码格式的转义形式 示例防止泄漏的另一种方法 第十二章 控制值的转换 类和属性参数 ESCAPE CONTENT XMLTIMEZONE DISPLAYLIST VALUELIST XMLDEFAULTVALUE XMLLISTPARAMETER XMLSTREAMMODE 介绍 支…...

SQL并集、交集、差集使用

一、概述 SQL语句实现数据的并集&#xff08;union&#xff09;、交集&#xff08;intersect&#xff09;、差集&#xff08;except&#xff09;。 二、案例 1、stu表 idname1张三2李四3王二 2、并集 union union 运算&#xff1a;表示取并集&#xff0c;例如&#xff1a…...

【双指针】盛水最多的容器

盛水最多的容器 文章目录 盛水最多的容器题目描述算法原理思路一思路二 代码实现Java代码实现C代码实现 题目描述 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与…...

win11,引导项管理

1&#xff0c;打开cmd,输入msconfig 2,进入引导选项卡 3&#xff0c;删除不需要的引导项...

YoloV8改进策略:WaveletPool解决小目标的混叠问题,提高小目标的检测精度

文章目录 摘要论文:《抗混叠在微小目标检测中的重要性》1、简介2、相关研究2.1、微小物体检测2.2. 抗锯齿过滤器3、方法3.1. Wavelet Pooling3.2 一致顺序的Wavelet Pooling的WaveCNet3.3、Bottom-Heavy Backbone4、实验4.1、预训练数据集4.2、微小目标检测数据集4.3、抗混叠方…...

JavaScript中的假值对象是什么?

JavaScript是一种非常灵活且强大的编程语言&#xff0c;但有时候它的一些特性可能会让人感到困惑。其中一个常见的问题就是假值对象。在本文中&#xff0c;我们将探讨什么是假值对象&#xff0c;并通过代码示例来解释这个概念。 什么是假值对象&#xff1f; 在JavaScript中&am…...

求二叉树的最大密度(可运行)

最大密度&#xff1a;二叉树节点数值的最大值 如果没有输出结果&#xff0c;一定是建树错误&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 我设置输入的是字符型数据&#xff0c;比较的ASCII值。 输入&#xff1a;FBE###CE### 输…...

V100 GPU服务器安装CUDNN教程

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

RT-Thread Hoist_Motor PID

本节介绍的是一个举升电机&#xff0c;顾名思义&#xff0c;通过转轴控制物体升降&#xff0c;为双通道磁性译码器&#xff0c;利用电调进行操控&#xff0c;具体驱动类似于大学期间最大众的SG180舵机&#xff0c;在一定的频率下&#xff0c;通过调制脉宽进行控制。 设备介绍…...

css 实现文字流光效果

经过调研发现大多滑块验证码中&#xff0c;有一些文字流光效果&#xff0c;因此在这里简单实现一下。 实现主要利用background 渐变背景以及backgorund-clip:text实现。具体代码如下 css部分 .slide {width: 300px;height: 40px;border: 1px solid #ccc;border-radius: 8px;…...

3D格式转换工具

这里记录下自己之前做3D模型格式转换&#xff0c;包括做CAD模型格式转换辅助的一些开源仓库和工具 &#xff08;一&#xff09;转换成gltf工具 gltf作为3D界的jpg标准&#xff0c;如今已经有很多引擎对其进行了支持&#xff0c;这里单独把它列出来 1. obj转glft工具 git仓库…...

seismicunix基础-声波波动方程推导

seismicunix基础-声波波动方程推导 接触波动方程的研究人员都绕不开这个公式&#xff0c;这是在一维状态下波动方程 但是对于这个方程是怎样来的很少有人能说清楚&#xff0c;其中涉及到牛顿第二运动定律&#xff0c;物体的加速度与受到的力有关。 假设一维弦是大量紧密连接的质…...

2024电脑录屏软件排行第一Camtasia喀秋莎

真的要被录屏软件给搞疯了&#xff0c;本来公司说要给新人做个培训视频&#xff0c;想着把视频录屏一下&#xff0c;然后简单的剪辑一下就可以了。可谁知道录屏软件坑这么多&#xff0c;弄来弄去头都秃了&#xff0c;不过在头秃了几天之后&#xff0c;终于让我发现了一个值得“…...

MQTT通信协议使用说明

目录 1 MQTT连接属性1.1 服务器URL(Broker Address)1.2 客户端标识(clientID)1.3 用户名称 & 密码(User Name & Password)1.4 连接超时(Connection Timerout)1.5 心跳间隔 (KeepAlivelnterval)1.6 清除会话(cleanSession) 2 主题&消息2.1 主题2.1.1 订阅主题(SUBSC…...

mysql底层是如何存放数据的

总览 首先总的来说&#xff0c;分为四个层级&#xff0c;行页区段。行就是数据库里的一行数据。 但一次从磁盘读进内存的数据量是一页&#xff08;页是读写的单位&#xff0c;默认16KB一页&#xff09;&#xff0c;页分很多种类&#xff0c;例如数据页、溢出页、undo日志页。 …...

【代码随想录】刷题笔记Day33

前言 Day33虽说是一个月&#xff0c;但是从第一篇开始实际上已经过了8个月了&#xff0c;得抓紧啊 46. 全排列 - 力扣&#xff08;LeetCode&#xff09; 前面组合就强调过差别了&#xff0c;这道题是排序&#xff0c;因此每次要从头到尾扫&#xff0c;结合used数组 class So…...

AD从原理图到PCB超详细教程

AD超详细教程 前言一、建立一个工程模板二、原理图1.设计原理图。2.使用AD自带库和网上开源原理图库3.画原理图库4.编译原理图 三、PCB1.确定元器件尺寸大小2.绘制PCB Library①使用元器件向导绘制元件库②原理图与PCB的映射 3.绘制PCB①更新PCB②调整元件位置③布线④漏线检查…...

2023.11.20使用flask做一个简单图片浏览器

2023.11.20使用flask做一个简单图片浏览器 功能&#xff1a; &#xff08;1&#xff09;输入指定路径&#xff0c;打开文件夹 &#xff08;2&#xff09;判断文件格式为图片 &#xff08;3&#xff09;在前端进行预览 &#xff08;4&#xff09;使用bootstrap进行简单美化 ma…...

https和http的区别和优势

大家好&#xff0c;我是咕噜-凯撒&#xff0c;HTTP&#xff08;超文本传输协议&#xff09;和HTTPS&#xff08;安全超文本传输协议&#xff09;是用于在网络上传输数据的协议&#xff0c;HTTPS相比HTTP在数据传输过程中更加安全可靠&#xff0c;适合对数据安全性要求较高的场景…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...