【MyBatis】3、一文介绍如何用 MyBatis 进行多表级联查询

news/2024/11/27 23:46:22/

目录

  • 一、设置新插入记录的主键(id)到参数对象中
  • 二、PageHelper 分页插件
  • 三、多表关系
  • 四、一对一
  • 五、一对多
  • 六、多对多

一、设置新插入记录的主键(id)到参数对象中

<insert id="insert01" parameterType="Student">INSERT INTO student (name, money) VALUES (#{name}, #{money})<selectKey resultType="long" keyProperty="id" order="AFTER">SELECT LAST_INSERT_ID()</selectKey>
</insert>

在这里插入图片描述

执行了两条 SQL 语句


 <insert id="insert02"useGeneratedKeys="true"keyProperty="id"parameterType="Student">INSERT INTO student (name, money) VALUES (#{name}, #{money})</insert>

在这里插入图片描述

💜 只执行了一条 SQL 语句
💜 该写法需要数据库驱动支持(如:MySQL 支持,而 Oracle 不支持)

二、PageHelper 分页插件

  • PageHelper 是中国人开发的 MyBatis 分页插件
  • https://github.com/pagehelper/Mybatis-PageHelper

💦 添加 MAVEN 依赖

<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.2.0</version>
</dependency>

💦 在 mybatis-config.xml 中配置插件

<plugins><!-- PageHelper 插件 --><!-- interceptor 拦截器 --><plugin interceptor="com.github.pagehelper.PageInterceptor"><property name="reasonable" value="true"/></plugin>
</plugins>

reasonable 设置为 true:
① 当 pageNum <= 0 的时候,会自动获取第一页的数据
② 当 pageNum > pages(总页数) 的时候,会自动获取最后一页的数据


public class TestStudent {@Testpublic void testPage() {try (SqlSession sqlSession = MyBatisUtil.openSession(true)) {PageHelper.startPage(1, 5);List<Student> list = sqlSession.selectList("student.list");for (Student student : list) {System.out.println("testPage student: " + student);}}}
}
<mapper namespace="student"><sql id="sqlListAll">SELECT * FROM student</sql><resultMap id="resultMapStudent" type="com.pojo.po.Student"><id property="id" column="id"/><result property="createTime" column="create_time"/></resultMap><select id="list" resultMap="resultMapStudent"><include refid="sqlListAll"/></select>
</mapper>

三、多表关系

在这里插入图片描述
一对多:
在这里插入图片描述
一对一:

在这里插入图片描述

多对多:
在这里插入图片描述
在这里插入图片描述


# drop
DROP TABLE IF EXISTS bank_card;
DROP TABLE IF EXISTS id_card;
DROP TABLE IF EXISTS person_job;
DROP TABLE IF EXISTS person;
DROP TABLE IF EXISTS job;# person
CREATE TABLE person(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(20) NOT NULL
);# bank_card
CREATE TABLE bank_card(id INT PRIMARY KEY AUTO_INCREMENT,no VARCHAR(30) NOT NULL UNIQUE,amout DECIMAL(18, 2) NOT NULL,person_id INT NOT NULL,FOREIGN KEY (person_id) REFERENCES person(id)
);# id_card
CREATE TABLE id_card(id INT PRIMARY KEY AUTO_INCREMENT,no VARCHAR(30) NOT NULL UNIQUE,address VARCHAR(50) NOT NULL,person_id INT NOT NULL UNIQUE,FOREIGN KEY (person_id) REFERENCES person(id)
);# job
CREATE TABLE job(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(20) NOT NULL UNIQUE,duty VARCHAR(50) NOT NULL
);# person_job
CREATE TABLE person_job(person_id INT,job_id INT,PRIMARY KEY (person_id, job_id),FOREIGN KEY (person_id) REFERENCES person(id),FOREIGN KEY (job_id) REFERENCES job(id)
);# data
INSERT INTO person(name) VALUES ('Jack'), ('Rose'), ('Larry'), ('Mike'), ('Tom'), ('James');INSERT INTO id_card(no, address, person_id) VALUES 
('9527', '北京', 4),
('8866', '广州', 1),
('2495', '上海', 5),
('4378', '成都', 2),
('5454', '杭州', 6),
('9923', '深圳', 3);INSERT INTO bank_card(no, amout, person_id) VALUES 
('6223', 0, 1),
('75556', 2098.56, 2),
('5345', 1010000.56, 1),
('87876', 534423.34, 3),
('654645', 432.45, 1),
('5434534', 234765.19, 4),
('76853', 98945.39, 4),
('6456867', 435534.78, 1),
('4324654', 874343.99, 4),
('53455', 5.20, 2);INSERT INTO job(name, duty) VALUES 
('程序员', '每一天都在写新的bug和修改昨天的bug'),
('保安', '公司全系统物理安全保障专员'),
('网管', '世界互联网信息终端及人类信息科技部信息集成应用导师'),
('厨师', '类口腔神经末梢感应实验中心及绿色环保邮寄肥转换加工基地负责人'),
('贴膜', '智能高端移动设备表面高化合物平面处理'),
('搬砖', '长方体混泥土瞬间移动师'),
('算命', '主观性逻辑推论及心理引导'),
('理发师', '人体无用副组织切除手术主刀');INSERT INTO person_job(person_id, job_id) VALUES 
(1, 1),
(1, 3),
(1, 5),
(1, 7),
(2, 5),
(3, 1),
(3, 2),
(5, 3),
(5, 5),
(5, 7);

四、一对一

(1) 查询 person 信息, 同时查询出 person 对应的 id_card 信息

# 查询 person 信息, 同时查询出 person 对应的 id_card 信息
SELECTp.*,c.id c_id,c.`no` c_no,c.address c_address
FROMperson pLEFT JOIN id_card c ON p.id = c.person_id

💦 写法1

<mapper namespace="person"><select id="list1" resultType="Person">SELECTp.*,c.id `idCard.id`,c.no `idCard.no`,c.address `idCard.address`FROMperson pLEFT JOIN id_card c ON p.id = c.person_id</select></mapper>

自动映射到 Person 的 idCard 属性的 id、no、address 属性上面去

💦 写法2

<mapper namespace="person"><resultMap id="rmList2" type="Person"><id property="id" column="id"/><result property="name" column="name"/><!-- 映射 idCard --><association property="idCard" javaType="IdCard"><id property="id" column="c_id"/><result property="no" column="c_no"/><result property="address" column="c_address"/></association></resultMap><select id="list2" resultMap="rmList2">SELECTp.*,c.id c_id,c.`no` c_no,c.address c_addressFROMperson pLEFT JOIN id_card c ON p.id = c.person_id</select></mapper>

(2) 查询 id_card 信息, 同时查询出 id_card 对应的 person 信息

# 查询 id_card 信息, 同时查询出 id_card 对应的 person 信息
SELECTc.*,p.id p_id,p.NAME p_name 
FROMid_card cLEFT JOIN person p ON p.id = c.person_id
<mapper namespace="idCard"><resultMap id="rmList" type="IdCard"><id property="id" column="id"/><result property="no" column="no"/><result property="address" column="address"/><!-- 映射 person --><association property="person" javaType="Person"><id property="id" column="p_id"/><result property="name" column="p_name"/></association></resultMap><select id="list" resultMap="rmList">SELECTc.*,p.id p_id,p.NAME p_nameFROMid_card cLEFT JOIN person p ON p.id = c.person_id</select></mapper>

五、一对多

# 查询 person 信息, 同时查询出 person 对应的 bank_card 信息
SELECTp.*,b.id bankCard_id,b.no bankCard_no,b.amout bankCard_amount
FROMperson pLEFT JOIN bank_card b ON b.person_id = p.id
<mapper namespace="person"><resultMap id="rmListWithBankCard" type="Person"><id property="id" column="id"/><result property="name" column="name"/><!-- 映射 bank_card --><collection property="bankCards" ofType="BankCard"><id property="id" column="bankCard_id"/><result property="no" column="bankCard_no"/><result property="amount" column="bankCard_amount"/></collection></resultMap><select id="listWithBankCard" resultMap="rmListWithBankCard">SELECTp.*,b.id bankCard_id,b.no bankCard_no,b.amount bankCard_amountFROMperson pLEFT JOIN bank_card b ON b.person_id = p.id</select></mapper>

六、多对多

在这里插入图片描述

查询 person 信息, 同时查询出 job 信息:

SELECTp.*,j.id job_id,j.`name` job_name,j.duty job_duty 
FROMperson pLEFT JOIN person_job pj ON p.id = pj.person_idLEFT JOIN job j ON j.id = pj.job_id;
<mapper namespace="person"><resultMap id="rmListWithJob" type="Person"><id property="id" column="id"/><result property="name" column="name"/><collection property="jobs" ofType="Job"><id property="id" column="job_id"/><result property="name" column="job_name"/><result property="duty" column="job_duty"/></collection></resultMap><select id="listWithJob" resultMap="rmListWithJob">SELECTp.*,j.id job_id,j.`name` job_name,j.duty job_dutyFROMperson pLEFT JOIN person_job pj ON p.id = pj.person_idLEFT JOIN job j ON j.id = pj.job_id</select></mapper>

查询 job 列表,同时查询出从事该 job 的 person 列表:

<mapper namespace="job"><resultMap id="rmListWithPerson" type="Job"><id property="id" column="id"/><result property="name" column="name"/><result property="duty" column="duty"/><collection property="persons" ofType="Person"><id property="id" column="person_id"/><result property="name" column="person_name"/></collection></resultMap><select id="listWithPerson" resultMap="rmListWithPerson">SELECTj.*,p.id person_id,p.`name` person_nameFROMjob jLEFT JOIN person_job pj ON pj.job_id = j.idLEFT JOIN person p ON pj.person_id = p.id;</select></mapper>

http://www.ppmy.cn/news/340139.html

相关文章

企业级信息系统开发讲课笔记4.7 Spring Boot整合JPA

文章目录 零、学习目标一、Spring Data JPA概述1、Spring Data JPA简介2、Spring Data JPA基本使用3、使用Spring Data JPA进行数据操作的多种实现方式4、自定义Repository接口中的Transactional注解5、变更操作&#xff0c;要配合使用Query与Modify注解 二、Spring Boot整合JP…

图数据库(三):Neo4j中的Create和Merge

在上篇文章中&#xff0c;我们介绍了在项目中如何使用Java来操作Neo4j图数据库。今天我们就仔细的学习一下&#xff0c;Neo4j中如何创建节点&#xff0c;以及Create和Merge的区别使用。 Create的简单用法 在Neo4j中&#xff0c;我们使用Create来创建节点。 create(n:Role{na…

太空大战-第14届蓝桥杯国赛Scratch真题中级组第6题

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第148讲。 太空大战&#xff0c;本题是2023年5月28日上午举行的第14届蓝桥杯国赛Scratch图形化编程中级组真题第6题&am…

Android8.1 添加修改默认壁纸

关于壁纸的尺寸&#xff0c;建议静态壁纸的宽&#xff0c;高是&#xff1a;宽屏幕分辨率的宽*2&#xff0c;高屏幕分辨率的高&#xff1b;当然如果静态壁纸的宽&#xff0c;高与屏幕分辨率相等也是可以的&#xff0c;但是需要修改下代码不然Launcher workspace的背景会被拉伸。…

哈夫曼树和哈夫曼编码

一.哈夫曼树 1.哈夫曼树 哈夫曼树是一种用于编码的树形结构。它是通过将频率最低的字符反复组合形成的二叉树&#xff0c;使得出现频率高的字符具有较短的二进制编码&#xff0c;而出现频率低的字符具有较长的编码。 在哈夫曼树中&#xff0c;每个叶子节点都代表一个字符&am…

南卡和UHB电容笔哪款好用?国产平替电容笔对比

现在几乎每一人都有一款iPad设备&#xff0c;可以解决很多工作和学习上的问题&#xff0c;比如在办公室里处理文件&#xff0c;做一些简单的PPT&#xff0c;比如在学习的时候&#xff0c;记录一些笔记。如果直接用手指在ipad上打字&#xff0c;会让网页变得不整洁&#xff0c;不…

性价比高的学生用台灯哪款好?推荐最适合学生用的台灯

“书山有路勤为径&#xff0c;学海无涯苦作舟”&#xff0c;读书是孩子们成长的必由之路&#xff0c;读书能够让孩子静下心来、拓宽知识面、获得更多的人生认知和看法。学习台灯其实市面上挺多&#xff0c;但是专为阅读而设计的台灯却并不多见。 1、南卡护眼台灯pro NANK南卡护…

【安全运维】小微企业的安全运维工具用哪款好?

即使是小微企业&#xff0c;也同样面临着安全运维的困扰&#xff0c;同样面临着数据泄露、资产难管理的问题&#xff0c;因此选择一款合适的安全运维工具是非常必要的。那你知道小微企业的安全运维工具用哪款好&#xff1f; 小微企业的安全运维工具用哪款好&#xff1f; 【回…