JavaEE简单示例——MyBatis多对多关联映射

news2024/11/25 5:57:37

简单介绍:

在实际的开发中,多对多的查询也是非常常见的。比如一个订单可以有很多的商品,而一个商品也可以被很多的订单所包含,而这种时候,如果我们有需求查询某一个订单内包含的所有商品;或者查询购买这个商品的订单,那么就需要使用到我们的多对对查询关联映射。

在多对多查询的时候,我们需要引入到一个新的概念,叫做中间表。中间表的概念就是帮助我们维护订单表和商品的对应关系,也就是每一个订单对应的商品的编号,或者是每一个商品对应的订单的编号。我们在查询的时候,首先要根据订单的编号从中间表查询出对应的商品编号,然后通过商品编号在商品表中查询出具体的商品的信息,最后把查询结果与Java实体类映射在一起输出最终的查询结果。

而所谓的多对对,其实就是经过中间表被分成了中间表对订单表,中间表对商品表两个一对多的关系,而对于多对多的关系中,我们并不需要学习新的标签和属性,唯一需要注意的就是中间表的使用和表数据的填写即可。

使用方法:

多对多的使用方法和一对多的方法相同,其关键点在于SQL语句的编写,以及对于表关系和表字段有一个清晰的认知和明确的认识:

订单表:

其中,order_id表示订单的编号,user_id表示用户的编号,是之前用来查询一个用户对应多个订单的时候用来确定订单属于哪一个用户的字段,order_informaton是用来描述订单的字段。 

商品表:

good_id表示商品的编号,good_information是用来描述商品的字段 

中间表:

这个表就是用来描述订单和商品之间关系的中间表,order_id表示订单号,同一个订单号就表示来自于同一个订单;good_id表示商品编号,同一个商品编号表示同一个商品。这个表最重要的就是理解订单号和商品编号是如何对应的。 

创建表的SQL语句:

create table orders(
    order_id int,
    user_id int,
    order_information varchar(20)
);
# order_id表示的是订单的编号,user_id表示的是用户的编号,同一个用户编号表示属于同一个用户
insert into orders values (1,1,'我是张三的第一个订单'),
                          (2,1,'我是张三的第二个订单'),
                          (3,2,'我是李四的第一个订单'),
                          (4,2,'我是李四的第二个订单'),
                          (5,2,'我是李四的第三个订单'),
                          (6,2,'我是李四的第四个订单'),
                          (7,3,'我是王五的第一个订单');
select * from orders;


# 创建商品详情表,存储的是商品的详情,good_id表示商品的编号,good_information表示商品的详情介绍
create table goods(
    good_id int,
    good_information varchar(20)
);
insert into goods values (1,'JavaEE基础'),
                         (2,'Java基础'),
                         (3,'数据库基础'),
                         (4,'MySQL基础');
select * from goods;

# 创建中间表,用来对应订单与商品之间的关系
create table order_list(
    id int primary key auto_increment,
    order_id int,
    good_id int
);

insert into order_list values (null,1,1),
                              (null,1,2),
                              (null,2,1),
                              (null,2,3),
                              (null,3,1);
select * from order_list;

通过订单号查询订单内包含的商品信息的SQL语句:

# 通过订单编号查询订单内的商品详情
select * from orders where order_id = 1;
# 通过订单编号查询中间表中维护的订单与商品的信息,查询订单对应的商品的编号
select * from order_list where order_id = 1;
# 通过上一条语句的订单编号,从商品表查询商品的详细信息
select * from goods where good_id in (select order_list.good_id from order_list where order_id = 1);

查询结果:

最终就可以查询出1号订单包含的两个商品的详细信息

通过商品编号查询包含该商品的订单:

# 通过商品编号查询包含此商品的订单
select * from goods where good_id = 2;
# 通过商品编号从中间表查询包含该商品的订单的订单号
select * from order_list where good_id = 2;
# 通过上一条语句查询出的订单的编号,从订单表查询出包含此商品的订单的详细信息
select * from orders where order_id in (select order_id from order_list where good_id = 2);

查询结果:

最终就可以查询出包含1号商品的订单有三条

代码实现:

其实在这个章节,最难的部分就是SQL语句的编写,在我们完成了SQL语句的编写之后,剩下的就是根据我们之前学过的一对多的方式,确定我们的查询的顺序,以及我们类和表,属性与字段之间的关系这些细节之后,我们就可以开始代码和SQL映射文件的编写了。

我们首先使用嵌套查询的方式编写通过订单号查询订单包含的商品的详细信息:

SQL映射文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Mappers.more_to_more_select">
<!--    配置多对多查询中的使用订单号查询订单所包含的商品信息-->
<!--    首先是子查询-->
  <select id="selectGoodsById" resultType="Goods" parameterType="int">
    select * from goods where good_id in (select good_id from order_list where order_id = #{id})
  </select>
<!--  然后是配置父查询-->
  <select id="selectOrdersById" parameterType="int" resultMap="OrdersMapper">
    select * from orders where order_id = #{id}
  </select>
  <resultMap id="OrdersMapper" type="Orders">
    <collection property="goodsList"
                column="order_id"
                ofType="Goods"
                select="Mappers.more_to_more_select.selectGoodsById"
                javaType="java.util.List"/>
  </resultMap>
</mapper>

接口文件:

package Mappers;

import com.mybatis.POJO.Goods;
import com.mybatis.POJO.Orders;

import java.util.List;

public interface more_to_more_select {
    public List<Goods> selectGoodsById(int i);
    public List<Orders> selectOrdersById(int i);
}

测试类:

package Mappers;

import com.mybatis.POJO.Goods;
import com.mybatis.POJO.Orders;
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.Before;
import org.junit.Test;

import java.io.InputStream;

public class more_to_more_selectTest {
    SqlSession session = null;
    more_to_more_select mapper = null;

    @Before
    public void setUp() throws Exception {
        InputStream stream = Resources.getResourceAsStream("mybatis.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(stream);
        session = build.openSession(true);
        mapper = session.getMapper(more_to_more_select.class);
    }
    @Test
    public void testSelectGoodsById() {
        for (Goods goods : mapper.selectGoodsById(1)) {
            System.out.println(goods.toString());
        }
    }

    @Test
    public void testSelectOrdersById() {
        for (Orders orders : mapper.selectOrdersById(1)) {
            System.out.println(orders.toString());
        }
    }
}

运行结果:

可以看到跟我们之前查询的结果是一样的,1号订单包含两个商品 

注意点:

在这个案例中我们需要注意的就是中间表的创建,使用以及字段的作用,最后就是我们之前学习过的一对多查询的相关知识。

我们只演示了多对多查询中的使用嵌套查询的方式根据订单号查询订单包含的商品的详细信息,后面还有通过商品信息查询包含该商品的订单信息。以及使用嵌套结果集的方式进行查询等,有兴趣的可以自己尝试。

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

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

相关文章

本地启动nacos注册服务

1.下载启动nacos(我的路径2.D:\nacos-server-2.0.0\nacos\bin) 2.单点模式启动 startup.cmd -m standalone 3.打开本地服务mysql、redis 4.配置nacos Nacos <1>创建命名空间&#xff0c;名称和项目pom一致 <2>ncaos导入配置或新建配置 <3>修改配置&#x…

Java培训:深入解读函数式接口

函数式编程是一种编程规范或一种编程思想&#xff0c;简单可以理解问将运算或实现过程看做是函数的计算。 Java8为了实现函数式编程&#xff0c;提出了3个重要的概念&#xff1a;Lambda表达式、方法引用、函数式接口。现在很多公司都在使用lambda表达式进行代码编写&#xff0c…

花7000报了培训班,3个月后我成功“骗”进了阿里,月薪拿16K....

“月薪4000元不如报名学IT&#xff0c;挑战年薪百万”这是大多数培训班在互联网上宣传的口号&#xff0c;简单的16个字却戳中了很多人的痛点&#xff0c;同龄人买车买房&#xff0c;自己却拿着微薄的工资连好一点的房子都租不起&#xff0c;这句口号 彻底激起了底层员工的焦虑&…

Spring上下文生命周期

基于入口来分析 import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;Configuration ComponentScan public cl…

飞行机器人专栏(十)-- 异构多视角视觉系统

感知系统架构为满足天空端主控制器的诸如RGB-D图像处理等大容量数据吞吐、高速并行计算、实时运动控制以及通信和可视化任务的计算算力需求&#xff0c;同时优化功耗表现&#xff0c;采用了结构紧凑、功耗表现优异的边缘计算硬件NVIDA IJetson AGXOrin 。该开发者套件包含高性能…

Python学习笔记202302

1、numpy.empty 作用&#xff1a;根据给定的维度和数值类型返回一个新的数组&#xff0c;其元素不进行初始化。 用法&#xff1a;numpy.empty(shape, dtypefloat, order‘C’) 2、logging.debug 作用&#xff1a;Python 的日志记录工具&#xff0c;这个模块为应用与库实现了灵…

可用于标记蛋白质216699-36-4,6-ROX,SE,6-羧基-X-罗丹明琥珀酰亚胺酯

一.6-ROX&#xff0c;SE产品描述&#xff1a;6-羧基-X-罗丹明琥珀酰亚胺酯&#xff08;6-ROX&#xff0c;SE&#xff09;是一种用于寡核苷酸标记和自动DNA测序的荧光染料&#xff0c;可用于标记蛋白质&#xff0c;寡核苷酸和其他含胺分子的伯胺&#xff08;-NH2&#xff09;。西…

Git中遇到的问题

文章目录Clone克隆bytes of body are still expectedunable to access此文章是自己在Git操作时遇到的问题&#xff0c;先开个坑记录下来&#xff0c;如果以后还遇到了Git上的其他问题&#xff0c;会在后面进行添加。Clone克隆 bytes of body are still expected Clone失败信息…

【Redis】Java客户端JedisSpringDataRedis入门(三)

&#x1f697;Redis学习第三站~ &#x1f6a9;起始站&#xff1a;【Redis】概述&环境搭建(一) &#x1f6a9;本文已收录至专栏&#xff1a;数据库学习之旅 &#x1f44d;希望您能有所收获 在上一篇中我们学习了Redis常见命令的使用&#xff0c;显然&#xff0c;我们不可能一…

Day21【元宇宙的实践构想07】—— 元宇宙与人工智能

&#x1f483;&#x1f3fc; 本人简介&#xff1a;男 &#x1f476;&#x1f3fc; 年龄&#xff1a;18 &#x1f91e; 作者&#xff1a;那就叫我亮亮叭 &#x1f4d5; 专栏&#xff1a;元宇宙 0.0 写在前面 “元宇宙”在2021年成为时髦的概念。元宇宙到底是什么&#xff1f;元宇…

[架构之路-123]-《软考-系统架构设计师》-操作系统-2-操作系统原理 - 存储层次结构与存储管理(寄存器、Cache、MMU、内存、外存、页表)

前言&#xff1a;操作系统的本质就是创建一个并发的应用程序执行的环境&#xff0c;使得各种应用程序可以动态、共享相同的计算机物理硬件资源&#xff0c;计算机的三大物理资源包括&#xff1a;CPU内存外设应用程序&#xff08;管理应用程序&#xff09;&#xff1a;以进程和现…

线性代数学习-1

线性代数学习-1行图像和列图像行图像列图像总结本文转载于https://herosunly.blog.csdn.net/article/details/88698381 该文章本人认为十分有用&#xff0c;便自己敲一遍笔记加固印象原文链接 原文这个笔记感觉比我老师讲的更加透彻&#xff0c;清晰。很好的展示了线性代数的原…

【MySQL】数据库中锁和事务的相关知识点

1.事务的四大特点 原子性&#xff1a;事务中的所有操作要么都成功&#xff0c;要么都失败。所有的操作是一个不可分割的单位。一致性&#xff1a;一致性指的是事务执行前后&#xff0c;数据从一个合法性状态转移到另一个合法性状态。这个状态和业务有关&#xff0c;是自己定义…

基于ssm框架大学生社团管理系统(源码+数据库+文档)

一、项目简介 本项目是一套基于ssm框架大学生社团管理系统&#xff0c;主要针对计算机相关专业的正在做bishe的学生和需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目可以直接作为bishe使用。 项目都经过严格调试&#xff0c;确保可…

在线文本翻译能力新增14个直译模型,打造以中文为轴心语言的翻译系统

经济全球化的今天&#xff0c;人们在工作和生活中经常会与外语打交道。相较传播性较广的英语而言&#xff0c;其他语种的识别和阅读对大多数人来说是一件难事&#xff0c;此时就需要借助语言翻译软件来帮助理解。 华为 HMS Core 机器学习服务&#xff08;ML Kit&#xff09;翻…

JVM详解——内存结构

文章目录内存结构1、 运行时数据区2、虚拟机栈3、本地方法栈4、程序计数器5、 堆6、方法区7、运行时常量池8、内存溢出和内存泄漏9、 堆溢出内存结构 1、 运行时数据区 Java虚拟机在运行Java程序期间将管理的内存划分为不同的数据区&#xff0c;不同的区域负责不同的职能&…

[YOLO] yolo理解博客笔记

YOLO v2和V3 关于设置生成anchorbox&#xff0c;Boundingbox边框回归的过程详细解读 YOLO v2和V3 关于设置生成anchorbox&#xff0c;Boundingbox边框回归的个人理解https://blog.csdn.net/shenkunchang1877/article/details/105648111YOLO v1网络结构计算 Yolov1-pytorch版 …

ChatGPT修炼指南和它的电力畅想

近期&#xff0c;ChatGPT刷屏各大社交平台&#xff0c;无疑成为人工智能界最靓的仔&#xff01; 身为一款“会说话”的聊天机器人程序&#xff0c;它与前辈产品Siri、小度、微软小冰等有什么不同&#xff1f;先来听听小伙伴们怎么说。 ChatGPT何以修炼得这么强大&#xff1f;…

什么叫骨传导概念耳机,骨传导耳机的原理是什么

骨传导耳机在蓝牙耳机当中是属于十分特殊传输声音的一种方式&#xff0c;开放式传输声音&#xff0c;其使用优点也受到越来越多人的熟知和喜爱&#xff0c;但还有一部分朋友们不知道骨传导耳机传输声音的原理是啥&#xff0c;下面就给大家简单科普一下。骨传导耳机是利用内置的…

BurpSuite实战教程03-BurpSuite插件开发

burp插件开发 Burp Suite的强大除了自身提供了丰富的可供测试人员使用的功能外&#xff0c;其提供的支持第三方拓展插件的功能也极大地方便使用者编写自己的自定义插件。&#xff0c;Burp Suite支持的插件类型有Java、Python、Ruby三种。无论哪种语言的实现&#xff0c;开发者…