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

MyBatis关联关系映射详解

前言

在使用MyBatis进行数据库操作时,关联关系映射是一个非常重要的概念。它允许我们在数据库表之间建立关联,并通过对象之间的关系来进行数据查询和操作。本文将详细介绍MyBatis中的关联关系映射,包括一对一、一对多和多对多关系的处理方法。

一、 什么是关联关系映射?

关联关系映射是指在数据库表之间建立关联关系,并将这种关系映射到对象之间的关系。在关系型数据库中,我们通常使用外键来建立表与表之间的关联。

在 MyBatis 中,通过 association 元素来处理对象与对象之间关联关系,association 元素提供了一系列属性用于维护数据表之间的关系。association 元素是 resultMap元素的子元素,它有两种配置方式,嵌套查询方式和嵌套结果映射方式。

二、MyBatis的关系映射方式

MyBatis提供了两种主要的关系映射方式:基于XML配置基于注解

1.基于XML配置的关系映射

在基于XML配置的方式中,我们需要编写一个XML文件来描述数据库表和Java对象之间的映射关系。这个XML文件通常包含以下几个部分:

  • 数据库连接信息:包括数据库的URL、用户名、密码等。
  • SQL语句:包括查询、插入、更新、删除等操作的SQL语句。
  • 结果映射:将查询结果映射到Java对象的属性上。

通过这个XML文件,MyBatis可以根据配置信息自动生成对应的SQL语句,并将查询结果映射到Java对象上。

2.基于注解的关系映射

在基于注解的方式中,我们可以使用注解来描述数据库表和Java对象之间的映射关系。通过在Java对象的属性上添加注解,我们可以指定该属性对应的数据库字段名、数据类型等信息。

相比于XML配置方式,基于注解的方式更加简洁和灵活。但是需要注意的是,注解方式不支持动态SQL语句的生成,因此在一些复杂的场景下可能不太适用。

三、如何使用MyBatis进行关系映射?

要使用MyBatis进行关系映射,我们需要完成以下几个步骤:

  1. 引入MyBatis的依赖:在项目的配置文件中添加MyBatis的依赖,以便能够使用MyBatis的功能。
  2. 配置数据库连接信息:在配置文件中添加数据库的连接信息,包括URL、用户名、密码等。
  3. 编写SQL语句:根据业务需求,编写对应的SQL语句,包括查询、插入、更新、删除等操作。
  4. 定义Java对象:定义与数据库表对应的Java对象,并在对象的属性上添加注解或在XML文件中进行配置。
  5. 执行数据库操作:通过MyBatis提供的API,执行数据库操作,包括查询、插入、更新、删除等操作。

四、关于关系映射的一些建议

  • 尽量使用基于注解的关系映射方式,因为它更加简洁和灵活。
  • 在编写SQL语句时,尽量使用参数化查询,以避免SQL注入攻击。
  • 在定义Java对象时,尽量使用包装类而不是基本类型,以避免空指针异常。
  • 在执行数据库操作时,尽量使用事务来保证数据的一致性和完整性。

五、关联关系映射

数据库表

1.一对一关联关系映射

一对一关联关系是指两个表之间的关系是一对一的。在数据库中,我们可以通过外键来建立这种关系。在MyBatis中,我们可以使用嵌套查询或嵌套结果映射来处理一对一关系。

嵌套查询

嵌套查询是指在查询主表的同时,通过子查询查询关联表的数据。在MyBatis中,我们可以使用<select>标签来定义子查询,并通过resultMap将查询结果映射到对象中。

<select id="getUserWithAddress" resultMap="userResultMap">SELECT * FROM userWHERE id = #{id}
</select><resultMap id="userResultMap" type="com.ctb.vo.User"><id property="id" column="id"/><result property="name" column="name"/><association property="address" javaType="Address"><id property="id" column="address_id"/><result property="city" column="city"/><result property="street" column="street"/></association>
</resultMap>

嵌套结果映射

嵌套结果映射是指将主表和关联表的查询结果分别映射到不同的对象中,并通过对象之间的关系建立关联。在MyBatis中,我们可以使用<resultMap>标签的<collection>子标签来定义嵌套结果映射。

<select id="getUserWithAddress" resultMap="userResultMap">SELECT u.id, u.name, a.id as address_id, a.city, a.streetFROM user uJOIN address a ON u.address_id = a.idWHERE u.id = #{id}
</select><resultMap id="userResultMap" type="com.ctb.vo.UserVo"><id property="id" column="id"/><result property="name" column="name"/><collection property="addresses" ofType="Address"><id property="id" column="address_id"/><result property="city" column="city"/><result property="street" column="street"/></collection>
</resultMap>

2.一对多关联关系映射

一对多关联关系是指一个表的一条记录对应多个关联表的记录。在数据库中,我们可以通过外键来建立这种关系。在MyBatis中,我们可以使用嵌套查询或嵌套结果映射来处理一对多关系。

嵌套查询

嵌套查询是指在查询主表的同时,通过子查询查询关联表的数据。在MyBatis中,我们可以使用<select>标签来定义子查询,并通过resultMap将查询结果映射到对象中。

<select id="getUserWithOrders" resultMap="userResultMap">SELECT * FROM userWHERE id = #{id}
</select><resultMap id="userResultMap" type="com.ctb.vo.User"><id property="id" column="id"/><result property="name" column="name"/><collection property="orders" ofType="Order"><id property="id" column="order_id"/><result property="name" column="order_name"/></collection>
</resultMap>

嵌套结果映射

嵌套结果映射是指将主表和关联表的查询结果分别映射到不同的对象中,并通过对象之间的关系建立关联。在MyBatis中,我们可以使用<resultMap>标签的<collection>子标签来定义嵌套结果映射。

<select id="getUserWithOrders" resultMap="userResultMap">SELECT u.id, u.name, o.id as order_id, o.name as order_nameFROM user uJOIN orders o ON u.id = o.user_idWHERE u.id = #{id}
</select><resultMap id="userResultMap" type="com.ctb.vo.User"><id property="id" column="id"/><result property="name" column="name"/><collection property="orders" ofType="Order"><id property="id" column="order_id"/><result property="name" column="order_name"/></collection>
</resultMap>

3.多对多关联关系映射

多对多关联关系是指两个表之间的关系是多对多的。在数据库中,我们需要通过中间表来建立这种关系。在MyBatis中,我们可以使用嵌套查询或嵌套结果映射来处理多对多关系。

嵌套查询

嵌套查询是指在查询主表的同时,通过子查询查询关联表的数据。在MyBatis中,我们可以使用<select>标签来定义子查询,并通过resultMap将查询结果映射到对象中。

<select id="getUserWithRoles" resultMap="userResultMap">SELECT * FROM userWHERE id = #{id}
</select><resultMap id="userResultMap" type="com.ctb.vo.User"><id property="id" column="id"/><result property="name" column="name"/><collection property="roles" ofType="Role"><id property="id" column="role_id"/><result property="name" column="role_name"/></collection>
</resultMap>

嵌套结果映射

嵌套结果映射是指将主表和关联表的查询结果分别映射到不同的对象中,并通过对象之间的关系建立关联。在MyBatis中,我们可以使用<resultMap>标签的<collection>子标签来定义嵌套结果映射。

<select id="getUserWithRoles" resultMap="userResultMap">SELECT u.id, u.name, r.id as role_id, r.name as role_nameFROM user uJOIN user_role ur ON u.id = ur.user_idJOIN role r ON ur.role_id = r.idWHERE u.id = #{id}
</select><resultMap id="userResultMap" type="com.ctb.vo.User"><id property="id" column="id"/><result property="name" column="name"/><collection property="roles" ofType="Role"><id property="id" column="role_id"/><result property="name" column="role_name"/></collection>
</resultMap>

4.Vo类是什么 

VO类是指值对象(Value Object),它是一种在计算机编程中常用的概念。值对象是一种用于封装数据的对象,它的主要作用是表示某个特定的值或一组相关的值。

在软件开发中,我们经常需要处理各种数据,比如用户信息、订单信息等。而值对象就是用来表示这些数据的。它通常包含一些属性(比如姓名、年龄、价格等),这些属性的值可以根据需要进行修改。

与值对象相关的一个重要概念是不可变性。值对象通常是不可变的,也就是说一旦创建了一个值对象,它的属性值就不能再被修改。这样可以确保值对象的数据始终保持一致性,避免了数据被意外修改的风险。

值对象在软件开发中有很多应用场景,比如在领域驱动设计中,可以用值对象来表示领域中的概念;在数据传输中,可以用值对象来封装需要传输的数据;在函数式编程中,值对象可以作为函数的参数或返回值。

下面简单编写一下VO类,以及编写测试类一对多的关系(其它就不过多赘述了)

package com.ctb.vo;import com.ctb.model.User;
import com.ctb.model.UserRole;import java.util.ArrayList;
import java.util.List;/*** @author 彪* @remark* @create  */
public class UserVo extends User{private List<UserRole> userroles = new ArrayList<>();public List<UserRole> getUserRoles() {return userRole;}public void setUserRoles(List<UserRole> userRoles) {this.userRoles = userRoles;}
}

 测试类

package com.ctb.biz;import com.ctb.vo.UserVo;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/*** @author 彪* @remark* @create  */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-mybatis.xml"})
public class UserBizTest {@Autowiredprivate UserBiz userBiz;@Testpublic void selectByUid() {//获取用户信息UserVo userVo = userBiz.selectByUid(7);System.out.println(userVo);
//获取角色信息userVo.getUserRole().forEach(System.out::println);}
}

六、总结

        关联关系映射是MyBatis中非常重要的概念之一。通过合理地使用关联关系映射,我们可以更加方便地进行数据库操作,并提高代码的可读性和可维护性。在实际开发中,我们应根据具体的业务需求来选择合适的关联关系映射方式,并合理地设计数据库表结构。 

相关文章:

MyBatis关联关系映射详解

前言 在使用MyBatis进行数据库操作时&#xff0c;关联关系映射是一个非常重要的概念。它允许我们在数据库表之间建立关联&#xff0c;并通过对象之间的关系来进行数据查询和操作。本文将详细介绍MyBatis中的关联关系映射&#xff0c;包括一对一、一对多和多对多关系的处理方法…...

常用电子元器件基础知识

目录 一、电阻 二、电容 三、电感 四、保险丝 五、二极管 一、电阻 概念&#xff1a;顾名思义&#xff0c;就是增加电流通过的阻力的。 就像是在水渠中放入东西&#xff0c;能阻止水的顺利通过也是一个道理。 基于电阻的电气特性&#xff0c;电阻在电路中主要有以下四个…...

git撤销还未push的的提交

怎样撤销掉上图中的提交呢 使用以下代码即可提交 git reset --soft HEAD^...

MySQL--数据库基础

数据库分类 数据库大体可以分为 关系型数据库 和 非关系型数据库 常用数据类型 数值类型&#xff1a; 分为整型和浮点型&#xff1a; 字符串类型 日期类型...

Excel相关笔记

1、找出B列中A列没有的数据并放在C列 公式&#xff1a;IF(ISNA(VLOOKUP(B1,$A 1 : 1: 1:A$4,1,FALSE)),B1,“”)...

RouterOS-配置PPPoEv4v6 Server

1 接口 ether3 出接口 ether4 内网接口 2 出接口 出接口采用PPPoE拨号SLAAC获取前缀&#xff0c;手动配置后缀 2.1 选择出接口interface&#xff0c;配置PPPoE client模式 2.2 配置PPPoE client用户名和密码 2.3 从PPPoE client获取前缀地址池 2.4 给出接口选择前缀并配置…...

PhpStorm软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 PhpStorm是一款由JetBrains开发的专业PHP集成开发环境&#xff08;IDE&#xff09;&#xff0c;旨在提供全面的PHP开发支持。它是基于IntelliJ IDEA平台构建的&#xff0c;具有强大的功能和工具&#xff0c;可以帮助开发人员提高…...

JavaScript设计模式(三)——单例模式、装饰器模式、适配器模式

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…...

LeetCode:有序数组的平方

题目 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 示例 1&#xff1a; 输入&#xff1a;nums [-4,-1,0,3,10] 输出&#xff1a;[0,1,9,16,100] 解释&#xff1a;平方后&#xff0c;数组变…...

数学分析:势场

首先从散度的物理解释开始。首先&#xff0c;在球内的向量场的散度的积分&#xff0c;等于它在球边界上的流量的积分。所以根据积分中值定理&#xff0c;我们可以这么理解散度&#xff0c;它就是这个体积内的速度场的平均密度。而速度场只和源有关&#xff0c;所以它表示的某个…...

MySQL 中 MyISAM 与 InnoDB 引擎的区别

分析&回答 区别很多&#xff0c;大家说出下面几点&#xff0c;面试就应该 OK 了 1) 事务支持 MyISAM不支持事务&#xff0c;而InnoDB支持。InnoDB的AUTOCOMMIT默认是打开的&#xff0c;即每条SQL语句会默认被封装成一个事务&#xff0c;自动提交&#xff0c;这样会影响速…...

【javascript】禁止浏览器调试前端页面

目录 为啥要禁止&#xff1f;无限 debugger基础禁止调试解决对策 为啥要禁止&#xff1f; 由于前端页面会调用很多接口&#xff0c;有些接口会被别人爬虫分析&#xff0c;破解后获取数据&#xff0c;为了杜绝这种情况&#xff0c;最简单的方法就是禁止人家调试自己的前端代码 …...

Oracle Non-CDB配置 TDE(透明数据加密) 的过程

说明 此文档虽然是针对non CDB而写&#xff0c;但是对于CDB的操作过程也是类似的&#xff0c;即在CDB$ROOT中设置完成wallet设置后&#xff0c;在PDB中设置和打开MEK即可。 先决条件 请确保目录$ORACLE_SID/admin/$ORACLE_SID存在&#xff0c;例如此目录为: /u01/app/oracl…...

MySQL——常见问题

NULL和空值的区别 1、空值不占空间&#xff0c;NULL值占空间。当字段不为NULL时&#xff0c;也可以插入空值。 2、当使用 IS NOT NULL 或者 IS NULL 时&#xff0c;只能查出字段中没有不为NULL的或者为 NULL 的&#xff0c;不能查出空值。 3、判断NULL 用IS NULL 或者 is no…...

在FPGA上快速搭建以太网

在本文中&#xff0c;我们将介绍如何在FPGA上快速搭建以太网 &#xff08;LWIP &#xff09;。为此&#xff0c;我们将使用 MicroBlaze 作为主 CPU 运行其应用程序。 LWIP 是使用裸机设计以太网的良好起点&#xff0c;在此基础上我们可以轻松调整软件应用程序以提供更详细的应用…...

如何防范 AI 盗取你的密码

现如今&#xff0c;随着人工智能&#xff08;AI&#xff09;应用的普及和快速迭代&#xff0c;几乎任何人都可以轻而易举地利用AI进行密码破解之类的攻击。这已经引起了业界的担忧。下面&#xff0c;我将围绕着&#xff1a;密码破解究竟意味着什么&#xff0c;基于AI的密码猜测…...

华清远见第六课程作业day3

类 栈 #include <iostream>using namespace std;class Sta{ private:int *data;int top; public:Sta():data(new int(128)){top-1;cout<<"stack::无参构造:"<<endl;}~Sta(){delete data;cout<<"stack::析构函数:"<<this<…...

Rabbitmq配置定义

RabbitMQ 环境变量 RabbitMQ 的环境变量都是以"RABBITMQ_"开头的&#xff0c;可以在Shell 环境中设置&#xff0c;也可以在配置文件中定义。默认的配置文件如下&#xff1a; ## /etc/rabbitmq/rabbitmq-env.conf 定义配置文件&#xff1a; /va/lib/rabbitmq/ 的目…...

2023年数模国赛时间分配

2023年数模国赛时间分配 写在前面赛前准备第一天&#xff08;9.7 18:00发布题目&#xff09;第二天&#xff08;9.8&#xff09;第三天&#xff08;9.9&#xff09;第四天&#xff08;9.10 20:00提交&#xff09;总结 写在前面 国赛马上就要开始啦 今年的比赛时间是9月7日&…...

kubernetes(K8S)笔记

文章目录 大佬博客简介K8SDocker VS DockerDockerK8S简介K8S配合docker相比较单纯使用docker 大佬博客 Kubernetes&#xff08;通常缩写为K8s&#xff09;是一个用于自动化容器化应用程序部署、管理和扩展的开源容器编排平台。它的构造非常复杂&#xff0c;由多个核心组件和附加…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...