MyBatis的多表操作

1 MyBatis的多表操作

1.1 多表模型介绍

我们之前学习的都是基于单表操作的,而实际开发中,随着业务难度的加深,肯定需要多表操作的。

  • 多表模型分类 一对一:在任意一方建立外键,关联对方的主键。

  • 一对多:在多的一方建立外键,关联一的一方的主键。

  • 多对多:借助中间表,中间表至少两个字段,分别关联两张表的主键。

1.2 多表模型一对一操作

  1. 一对一模型: 人和身份证,一个人只有一个身份证

  2. 代码实现运行结果:

    1. 步骤一: sql语句准备
CREATE TABLE person(    
id INT PRIMARY KEY AUTO_INCREMENT,    
NAME VARCHAR(20),    
age INT);
INSERT INTO person VALUES (NULL,'张三',23);
INSERT INTO person VALUES (NULL,'李四',24);
INSERT INTO person VALUES (NULL,'王五',25);CREATE TABLE card(    
id INT PRIMARY KEY AUTO_INCREMENT,    number VARCHAR(30),   pid INT,    
CONSTRAINT cp_fk FOREIGN KEY (pid) REFERENCES person(id));INSERT INTO card VALUES (NULL,'12345',1);INSERT INTO card VALUES (NULL,'23456',2);INSERT INTO card VALUES (NULL,'34567',3);

创建实体对象

@Data
public class Card {private int id;private int number;private int pid;  // 可以不写private Person p;}
@Data
public class Person {private int id;private String name;private int age;
}

步骤二:编写dao接口

public interface OneToOneDao {//查询全部card数据public List<Card> findAll();
}

步骤三:配置文件

<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.zxy.dao.OneToOneDao"><!--配置字段和实体对象属性的映射关系--><resultMap id="oneToOne" type="card"><id column="cid" property="id"/><result property="number" column="number"/><!--实体类里面不包含 pid属性的话不需要这一句话--><result property="pid" column="cpid"/><!--association:配置被包含对象的映射关系property:被包含对象的变量名javaType:被包含对象的数据类型--><association property="p" javaType="person"><id column="pid" property="id"/><result property="name" column="name"/><result property="age" column="age"/></association></resultMap><!--    查询数据--><select id="findAll" resultMap="oneToOne">// 实体没有pid属性的时候使用以下语句select c.id cid,number,pid,name,age  from card c,person p where c.pid=p.id//包含pid属性的时候使用以下语句select  c.id cid,c.pid cpid,number,pid,name,age from card c , person p where c.pid=p.id</select>
</mapper>

步骤四:配置核心配置文件

<mapper resource="cn/zxy/dao/onetoOneDao.xml"/>

步骤五:测试类

@Testpublic void onetest(){SqlSession sqlSession = MybatisUtils.getSqlSession(true);//获取UserDao接口实现类对象OneToOneDao mapper = sqlSession.getMapper(OneToOneDao.class);List<Card> list = mapper.findAll();for (Card card : list) {System.out.println(card);}MybatisUtils.closeSqlSession(sqlSession);}

运行结果:

在这里插入图片描述

一对一配置总结

<resultMap>:配置字段和对象属性的映射关系标签。id 属性:唯一标识type 属性:实体对象类型
<id>:配置主键映射关系标签。
<result>:配置非主键映射关系标签。column 属性:表中字段名称property 属性: 实体对象变量名称
<association>:配置被包含对象的映射关系标签。property 属性:被包含对象的变量名javaType 属性:被包含对象的数据类型

1.3 多表模型一对多操作

  1. 一对多模型: 一对多模型:班级和学生,一个班级可以有多个学生。

  2. 代码实现

    1. 步骤一: sql语句准备
CREATE TABLE classes(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20)
);
INSERT INTO classes VALUES (NULL,'211一等班级');
INSERT INTO classes VALUES (NULL,'211二等班级');CREATE TABLE student(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(30),age INT,cid INT,CONSTRAINT cs_fk FOREIGN KEY (cid) REFERENCES classes(id)
);
INSERT INTO student VALUES (NULL,'张三',23,1);
INSERT INTO student VALUES (NULL,'李四',24,1);
INSERT INTO student VALUES (NULL,'王五',25,2);
INSERT INTO student VALUES (NULL,'赵六',26,2);

实体类准备

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Classes {private Integer id;     //主键idprivate String name;    //班级名称private List<Student> students; //班级中所有学生对象}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {private Integer id;     //主键idprivate String name;    //学生姓名private Integer age;    //学生年龄
}

步骤二:添加dao接口对象

public interface OneToManyDao {public List<Classes> findAll();
}

步骤三:配置文件

<mapper namespace="com.by.dao.OneToManyDao"><resultMap id="oneToMany" type="classes"><id column="cid" property="id"/><result column="name" property="name"/><!--collection:配置被包含的集合对象映射关系property:被包含对象的变量名ofType:被包含对象的实际数据类型--><collection property="students" ofType="student"><id column="sid" property="id"></id><result column="name" property="name"/><result column="age" property="age"/></collection></resultMap>
<select id="findAll" resultMap="oneToMany">select c.id cid,c.name,s.id sid,s.name,s.age  from classes c,student s where c.id=s.cid
</select>
</mapper>

步骤四:配置核心文件

<mapper resource="com/by/dao/OneToManyDao.xml"/>

步骤五:测试类

 @Testpublic void onemanytest(){SqlSession sqlSession = MybatisUtils.getSqlSession(true);//获取UserDao接口实现类对象OneToManyMapper mapper = sqlSession.getMapper(OneToManyMapper.class);List<Classes> list = mapper.findAll();for (Classes classes : list) {System.out.println(classes);}MybatisUtils.closeSqlSession(sqlSession);}

一对多配置文件总结:

<resultMap>:配置字段和对象属性的映射关系标签。id 属性:唯一标识type 属性:实体对象类型
<id>:配置主键映射关系标签。
<result>:配置非主键映射关系标签。column 属性:表中字段名称property 属性: 实体对象变量名称
<collection>:配置被包含集合对象的映射关系标签。property 属性:被包含集合对象的变量名ofType 属性:集合中保存的对象数据类型

什么是延迟加载?

问题

在开发过程中很多时候我们并不需要总是在加载用户信息时就一定要加载他的订单信息,此时就是我们所说的延迟加载

举个例子

*在一对多中,当我们有一个用户,它有个100个订单
在查询用户的时候,要不要把关联的订单查出来?
在查询订单的时候,要不要把关联的用户查出来?
* 回答
在查询用户时,用户下的订单应该是,什么时候用,什么时候查询。
在查询订单时,订单所属的用户信息应该是随着订单一起查询出来。

延迟加载

就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据
延迟加载也称懒加载。

优点:先从单表查询,需要时再从关联表去关联查询,⼤⼤提⾼数据库性能,因为查询单表要比关联查询多张表速度要快。
缺点:因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成⽤户等待时间变长,造成用户体验下降。
在多表中:一对多,多对多:通常情况下采用延迟加载一对一(多对一):通常情况下采用立即加载
注意:
延迟加载是基于嵌套查询来实现的 

局部延迟加载实现:

一对一延迟加载:

创建Personmapper接口

public interface PersonMapper {public List<Person> findById(Integer id);
}

创建mapper映射文件:

<mapper namespace="cn.zxy.mapper.PersonMapper"><select id="findById" resultType="person">select * from person where id=#{id}</select>
</mapper>

修改一对一映射文件:

<mapper namespace="cn.zxy.mapper.OneToOneMapper"><!--配置字段和实体的关系 映射关系--><resultMap id="OneToOne" type="card"><id property="id" column="id"/><result property="number" column="number"/><result property="pid" column="pid"/><!--fetchType 延迟加载 lazy 指的是懒加载eager 指的是默认立即加载select 是查询关键字 查询mapper接口里面的findById如果使用全局的延迟加载 那么就把fetchType 去掉,然后全局配置必须是true才开启延迟加载--><association property="p" column="pid" javaType="person"select="cn.zxy.mapper.PersonMapper.findById" fetchType="lazy"></association></resultMap><!--需要两个mapper映射文件配合使用--><select id="findAll" resultMap="OneToOne">select * from card</select>
</mapper>

一对多延迟加载

创建StuMapper接口:

public interface StudentMapper {public List<Student> findByCid(Integer id);
}

创建StuMapper映射文件:

<mapper namespace="cn.zxy.mapper.StudentMapper"><select id="findByCid" resultType="student">select * from student where cid=#{id}</select>
</mapper>

修改一对多映射文件:

<mapper namespace="cn.zxy.mapper.OneToManyMapper"><resultMap id="oneToMany" type="classes"><id column="id" property="id"/><result column="name" property="name"/><!--延迟加载 使用全局的延迟模式--><collection property="stu" column="id" ofType="student"select="cn.zxy.mapper.StudentMapper.findByCid" fetchType="eager"></collection></resultMap><select id="findAll" resultMap="oneToMany">select * from classes</select></mapper>

延迟加载的原理:

延迟加载主要是通过动态代理的形式实现,通过代理拦截到指定方法,执行数据加载。
在这里插入图片描述

1.4 多表模型多对多操作

多对多模型:学生和课程,一个学生可以选择多门课程、一个课程也可以被多个学生所选择。

代码实现

  • 步骤一: sql语句准备
CREATE TABLE course(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20)
);
INSERT INTO course VALUES (NULL,'语文');
INSERT INTO course VALUES (NULL,'数学');CREATE TABLE stu_cr(id INT PRIMARY KEY AUTO_INCREMENT,sid INT,cid INT,CONSTRAINT sc_fk1 FOREIGN KEY (sid) REFERENCES student(id),CONSTRAINT sc_fk2 FOREIGN KEY (cid) REFERENCES course(id)
);
INSERT INTO stu_cr VALUES (NULL,1,1);
INSERT INTO stu_cr VALUES (NULL,1,2);
INSERT INTO stu_cr VALUES (NULL,2,1);
INSERT INTO stu_cr VALUES (NULL,2,2);
  • 步骤二:实体类准备
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Course {private Integer id;     //主键idprivate String name;    //课程名称}
student类里面添加 课程集合@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {private Integer id;     //主键idprivate String name;    //学生姓名private Integer age;    //学生年龄private List<Course> courses;   // 学生所选择的课程集合
}

步骤三:创建dao接口

public interface ManyToManyDao {//查询学生全部数据 得到课表和班级public List<Student> findAll();
}

步骤四:配置文件

  • 数据库字段分析:
select sc.sid scid,s.id sid,s.name,s.age,c.id cid,c.name cname ,sc.id from student s, course c, stu_cr sc where sc.sid=s.id and s.cid=c.id
  • 映射文件编写
<mapper namespace="cn.zxy.dao.ManyToManyDao"><resultMap id="manyToMany" type="student"><id column="sid" property="id"/><result column="sname" property="name"/><result column="sage" property="age"/><!--property 指的是student里面定义的集合变量名ofType 指的是实体类对象--><collection property="courses" ofType="course"><id column="cid" property="id"/><result column="cname" property="name"/></collection></resultMap>
<select id="findAll" resultMap="manyToMany">select  sc.sid,s.name sname, s.age sage,c.name cname,sc.cid  from student s,course c,stu_cr sc where sc.sid=s.id and sc.cid=c.id
</select>
</mapper>

步骤五:测试类

@Testpublic void manytoTest(){SqlSession sqlSession = MybatisUtils.getSqlSession(true);//获取UserDao接口实现类对象ManyToManyDao mapper = sqlSession.getMapper(ManyToManyDao.class);List<Student> manylist = mapper.findAll();for (Student student : manylist) {System.out.println(student);}MybatisUtils.closeSqlSession(sqlSession);}

1.5 多表模型操作总结

<resultMap>:配置字段和对象属性的映射关系标签。id 属性:唯一标识type 属性:实体对象类型
<id>:配置主键映射关系标签。
<result>:配置非主键映射关系标签。column 属性:表中字段名称property 属性: 实体对象变量名称
<association>:配置被包含对象的映射关系标签。property 属性:被包含对象的变量名javaType 属性:被包含对象的数据类型
<collection>:配置被包含集合对象的映射关系标签。property 属性:被包含集合对象的变量名ofType 属性:集合中保存的对象数据类型

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

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

相关文章

实用便捷!一站式BI系统推荐

在企业数字化转型过程中&#xff0c;BI系统可以建立业务、数据的双驱引擎&#xff0c;形成业务、数据的互补作用&#xff0c;通过建立数字化技术架构&#xff0c;明确企业的战略定位和业务目标&#xff0c;从而支撑实现这个目标。而一站式BI系统&#xff0c;则是指可以轻松从数…

【MySQL】SQL性能分析 (七)

&#x1f697;MySQL学习第七站~ &#x1f6a9;本文已收录至专栏&#xff1a;MySQL通关路 ❤️文末附全文思维导图&#xff0c;感谢各位点赞收藏支持~ 假如我们需要对SQL进行优化&#xff0c;我们就必须对他足够的了解&#xff0c;比如 对哪一类SQL进行优化&#xff08;增删改查…

基于物联网网关的工业数据可视化平台有什么功能?

随着数字化浪潮的不断发展&#xff0c;工业数据的价值越来越重要。在企业利用数据的过程中&#xff0c;数据可视化是数字化系统中十分重要的一部分。然而&#xff0c;工厂多种设备、多种协议影响到系统的搭建使得企业无法获得全面的数据视图&#xff0c;也无法对整个生产流程进…

OJ练习第142题——路径总和 II

113. 路径总和 II 力扣链接&#xff1a;113. 路径总和 II 题目描述 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 Java代码&#xff08;深度优先搜…

六边形架构

六边形架构 微服务系统架构微服务定义微服务系统设计 传统分层架构六边形架构参考资料 微服务系统架构 需求描述做什么的问题&#xff0c;架构描述怎么做的问题(描述组成系统的各部件及其之间的关系) 微服务定义 下面的定义来自周志明老师的 凤凰架构 微服务是一种通过多个小型…

【Linux】 由“进程”过渡到“线程” -- 什么是线程(thread)?

知识引入初识线程1.什么叫做进程&#xff1f;2.什么叫做线程&#xff1f;3.如何看待我们之前学习的进程&#xff1f; 理解线程创建线程函数调用1.线程一旦被创建&#xff0c;几乎所有资源都是被线程所共享的2.与进程之间切换相比&#xff0c;线程的切换 初识线程总结&#xff1…

使用 Docker 快速上手中文版 LLaMA2 开源大模型

本篇文章&#xff0c;我们聊聊如何使用 Docker 容器快速上手朋友团队出品的中文版 LLaMA2 开源大模型&#xff0c;国内第一个真正开源&#xff0c;可以运行、下载、私有部署&#xff0c;并且支持商业使用。 写在前面 感慨于昨天 Meta LLaMA2 模型开放下载之后&#xff0c;Git…

操作系统练习:进程间通信(共享内存方式)

说明 本文是《操作系统概念(第九版)》3.4节“进程间通信”的练习。 进程间通信主要由两种模型&#xff1a; 共享内存消息传递 本文使用共享内存的方式实现进程间的通信 创建消息生产者 创建生产者的主要操作包括&#xff1a; 定义共享内存的大小、名称&#xff0c;以及通…

netty知识集锦2

粘包半包 粘包半包解决方案&#xff0c; 1短链接&#xff0c;它的消息边界是从链接建立到链接断开 2.定长解码器&#xff1a;服务器端选最大长度的消息作为定长&#xff0c;客户端不足补齐&#xff0c;缺点造成浪费 netty协议设计与解析 Message编码解码

AWS IAM介绍

前言 AWS是世界上最大的云服务提供商&#xff0c;它提供了很多组件供消费者使用&#xff0c;其中进行访问控制的组件叫做IAM(Identity and Access Management)&#xff0c; 用来进行身份验证和对AWS资源的访问控制。 功能 IAM的功能总结来看&#xff0c;主要分两种&#xff1…

《零基础入门学习Python》第060讲:论一只爬虫的自我修养8:正则表达式4

有了前面几节课的准备&#xff0c;我们这一次终于可以真刀真枪的干一场大的了&#xff0c;但是呢&#xff0c;在进行实战之前&#xff0c;我们还要讲讲正则表达式的实用方法和扩展语法&#xff0c;然后再来实战&#xff0c;大家多把持一会啊。 我们先来翻一下文档&#xff1a;…

openGauss学习笔记-17 openGauss 简单数据管理-表达式

文章目录 openGauss学习笔记-17 openGauss 简单数据管理-表达式17.1 简单表达式17.2 条件表达式17.3 子查询表达式17.4 数组表达式17.5 行表达式 openGauss学习笔记-17 openGauss 简单数据管理-表达式 表达式类似一个公式&#xff0c;我们可以将其应用在查询语句中&#xff0c…

25 MFC 数据库

文章目录 导入ADO库 导入ADO库 #import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","rsEOF")void CADODlg::OnBnClickedBtnQuery() {//导入ADO库::CoInitialize(NULL);//初始化COM库_ConnectionPtr pCo…

《面试1v1》如何提高远程用户的吞吐量

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

Flutter动画库:animations(路由过渡动画或者页面切换动画)

animations animations 是一个 Flutter 库&#xff0c;它提供了一组用于创建动画效果的工具和组件。这个库的核心重点是路由过渡动画或者页面切换动画 地址 https://pub-web.flutter-io.cn/packages/animations 安装 flutter pub add animations看了下官方文档和官方例子&a…

计科web常见错误排错【HTTP状态404、导航栏无法点开、字符乱码及前后端数据传输呈现、jsp填写的数据传到数据库显示null、HTTP状态500】

web排错记录 在使用javaweb的过程中会出现的一些错误请在下方目录查找。 目录 错误1&#xff1a;HTTP状态404——未找到 错误2&#xff1a;导航栏下拉菜单无法点开的问题 错误3&#xff1a;字符乱码问题 错误4&#xff1a;jsp网页全部都是&#xff1f;&#xff1f;&#x…

【单片机】MSP430F149单片机,晨启,音乐播放器,蜂鸣器音乐

四、音乐播放器 任务要求&#xff1a; 设计制作一个简易音乐播放器&#xff08;通过手柄板上的蜂鸣器发声&#xff0c;播放2到4首音 乐&#xff09;&#xff0c;同时LED模块闪烁&#xff0c;给人视、听觉美的感受。 评分细则&#xff1a; 按下播放按键P15开始播放音乐&#x…

【C++】继承基础知识及简单应用,使用reportSingleClassLayout(在Visual Studio开发人员命令提示窗口)查看派生类详细信息

author&#xff1a;&Carlton tag&#xff1a;C topic&#xff1a;【C】继承基础知识及简单应用&#xff0c;使用reportSingleClassLayout&#xff08;在Visual Studio开发人员命令提示窗口&#xff09;查看派生类详细信息 website&#xff1a;黑马程序员C date&#xf…

微信小程序原生上传图片和预览+云函数上传

1.前台页面 1.1wxml问阿金 <!-- 说明一个上传页面的按钮 --> <button type"primary" bindtap"uploadPage">上传页面展示</button> <!-- 声明一个上传服务器的按钮 --> <button type"warn" bindtap"uploadSeve…

第四讲:MySQL中DDL一些基本数据类型及表的创建、查询

目录 1、创建表:2、DDL一些基本数据类型&#xff1a; 1、创建表: 部分单词及解析&#xff1a; 1、tables:表 2、comment:评论&#xff0c;解释 3、gender:性别 4、neighbor&#xff1a;邻居 1、创建表&#xff1a;&#xff08;注&#xff1a;在自定义数据库操作&#xff0c;…