Mybatis之关联

一、一对多关联

eg:一个用户对应多个订单

建表语句

CREATE TABLE `t_customer` (
	 `customer_id` INT NOT NULL AUTO_INCREMENT, 
	 `customer_name` CHAR(100), 
	 PRIMARY KEY (`customer_id`) 
);
CREATE TABLE `t_order` ( 
	`order_id` INT NOT NULL AUTO_INCREMENT, 
	`order_name` CHAR(100), 
	`customer_id` INT, 
	PRIMARY KEY (`order_id`) 
); 
INSERT INTO `t_customer` (`customer_name`) VALUES ('张三');
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o1', '1'); 
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o2', '1'); 
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o3', '1'); 

关联查询:查询custmoer_id=1的用户的所有订单信息和用户信息

select t_customer.customer_id,customer_name,order_id,order_name from t_customer left JOIN t_order on t_customer.customer_id=t_order.customer_id
where t_customer.customer_id=1

在这里插入图片描述

Customer实体类:

@Data
public class Customer {
    private Integer customerId;
    private String customerName;
//一个顾客的所有订单
    private List<Order> orderList;
}

Order实体类:

@Data
public class Order {
    private Integer orderId;
    private String orderName;
    private Integer customerId;

}

mapper接口:

Customer getCustomerWithOrders(Integer customerId);

xml配置文件:

    <resultMap id="CustomerMap" type="Customer">
        <id property="customerId" column="customer_id"></id>
        <result property="customerName" column="customer_name"></result>

        <collection property="orderList" ofType="Order">
            <id property="orderId" column="order_id"></id>
            <result property="orderName" column="order_name"></result>
        </collection>

    </resultMap>

    <select id="getCustomerWithOrders" resultMap="CustomerMap">
        select t_customer.customer_id,customer_name,order_id,order_name from t_customer left JOIN t_order on t_customer.customer_id=t_order.customer_id
        where t_customer.customer_id=#{customerId}
    </select>

测试:

   @Test
    public void test01(){
        Customer customerWithOrders = orderMapper.getCustomerWithOrders(1);
        System.out.println(customerWithOrders);
    }

在“对多”关联关系中,同样有很多配置,但是提炼出来最关键的就是:“collection”和“ofType”

二、对一关联

eg:一个订单对应一个用户

sql语句:查询订单号为1的订单和用户信息

select t_order.* ,t_customer.customer_name from t_order LEFT JOIN t_customer on t_order.customer_id=t_customer.customer_id
where order_id=1;

查询结果:

在这里插入图片描述

order实体类新增Customer属性

@Data
public class Order {
    private Integer orderId;
    private String orderName;
    private Integer customerId;
    //对一关系,用户信息
    private Customer customer;
}

mapper接口:

    Order getOrderWithCustomer(Integer orderId);

xml配置文件:

    <resultMap id="OrderMap" type="Order">
        <id property="orderId" column="order_id"></id>
        <result property="orderName" column="order_name"></result>
        <association property="customer" javaType="Customer">
            <id property="customerId" column="customer_id"></id>
            <result property="customerName" column="customer_name"></result>
        </association>
    </resultMap>

    <select id="getOrderWithCustomer" resultMap="OrderMap">
        select t_order.* ,t_customer.customer_name from t_order LEFT JOIN t_customer on t_order.customer_id=t_customer.customer_id
        where order_id=#{orderId};

    </select>

测试:

   @Test
    public  void test02(){
        Order orderWithCustomer = orderMapper.getOrderWithCustomer(1);
        System.out.println(orderWithCustomer);
    }

三、OGNL风格的对一关联

<!--    OGNL风格的对一关联-->
    <select id="getOrderWithCustomer2" resultType="Order">
        select t_order.order_id,t_order.order_name,t_order.customer_id as 'customer.customerId',t_customer.customer_name as 'customer.customerName' from t_order LEFT JOIN t_customer on t_order.customer_id=t_customer.customer_id
        where order_id=#{orderId};
    </select>

注意起别名时,对象属性costomer.customerId要加上引号

四、多对多关联

eg:一本书对应多个种类,一个种类对应多本书

建立中间表将书和种类对应起来

①根据书的id,查询对应的具体信息和所属种类的信息:

mapper接口:

    /**
     * 根据书的id,查询对应的具体信息和所属种类的信息
     * @param bookId
     * @return
     */
    BookEntity selectBookOfCategories(Integer bookId);

xml配置文件:

    <resultMap id="BookMap" type="BookEntity">
        <id property="id" column="book_id"></id>
        <result property="name" column="name"></result>
        <collection property="categoryEntityList" ofType="CategoryEntity">
            <id property="categoryId" column="category_id"></id>
            <result property="categoryName" column="category_name"></result>
        </collection>
    </resultMap>

    <select id="selectBookOfCategories" resultMap="BookMap">
        select book_id,category.category_id,category_name,name
        from books,category,category_book
        WHERE books.id=category_book.book_id
          and category_book.category_id=category.category_id
          and books.id=#{value}
    </select>

②根据种类的id,查询所有对应书的信息

mapper接口:

  CategoryEntity getCategory(Integer id);

xml配置文件

   <resultMap id="CategoryMap" type="CategoryEntity">
        <id property="categoryId" column="category_id"></id>
        <result property="categoryName" column="category_name"></result>
        <collection property="bookEntityList" ofType="BookEntity">
            <id property="id" column="book_id"></id>
            <result property="name" column="name"></result>
        </collection>
    </resultMap>
    <select id="getCategory" resultMap="CategoryMap">
        SELECT name,category.category_id ,category_name,book_id
        from  books,category,category_book
        WHERE books.id=category_book.book_id
          and category_book.category_id=category.category_id
          and category.category_id=#{value};
    </select>

五、分步查询

①分步查询对多关联

根据id查询顾客=>设置resultMap=>collection中的select指定OrderMapper.xml中的根据顾客id查询所有订单的select语句=>column指定传参(顾客id)

CustomerMapper.xml

<resultMap id="CustomerMap" type="Customer">
    <id property="customerId" column="customer_id"></id>
    <result property="customerName" column="customer_name"></result>
    <collection property="orderList" select="com.iflytek.mapper.OrderMapper.selectOrderListById" column="customer_id"></collection>
</resultMap>

<select id="getOrderListByCustomerId" resultMap="CustomerMap">
    select * from t_customer where customer_id=#{id}
</select>

OrderMapper.xml

<select id="selectOrderListById" resultMap="OrderMap0">
    select * from t_order where customer_id=#{value}
</select>
<resultMap id="OrderMap0" type="Order">
    <id property="orderId" column="order_id"></id>
    <result property="orderName" column="order_name"></result>
</resultMap>

关系总览:

在这里插入图片描述

②分步查询对一关联

OrderMapper.xml

根据订单id查询订单具体信息=>association标签中的select指定CustomerMapper.xml中的根据customer_id查询顾客信息的slecect语句=>column指定传参customer_id

    <resultMap id="OrderMap2" type="Order">
        <id property="orderId" column="order_id"></id>
        <result property="orderName" column="order_name"></result>
        <association property="customer" select="com.iflytek.mapper.CustomerMapper.getCustomerById" column="customer_id">
        </association>
    </resultMap>
    

    <select id="getOrderAndCustomer" resultMap="OrderMap2">
        select * from t_order where order_id=#{orderId}
    </select>

CustomerMapper.xml

根据用户id查询用户具体信息

    <resultMap id="CustomerMap0" type="Customer">
        <id property="customerId" column="customer_id"></id>
        <result property="customerName" column="customer_name"></result>
    </resultMap>

<select id="getCustomerById" resultMap="CustomerMap0">
    select * from t_customer where customer_id=#{value}
</select>

关系总览:

在这里插入图片描述

六、延迟加载

查询到Customer的时候,不一定会使用Order的List集合数据。如果Order的集合数据始终没有使用,那么这部分数据占用的内存就浪费了。对此,我们希望不一定会被用到的数据,能够在需要使用的时候再去查询。

延迟加载的概念:对于实体类关联的属性到需要使用时才查询。也叫懒加载。

yml配置文件中开启懒加载

mybatis:
  configuration:
    #开启懒加载
    lazy-loading-enabled: true

测试:

@Test
public void testSelectCustomerWithOrderList() throws InterruptedException {

    //对多关联
    Customer customer = mapper.selectCustomerWithOrderList(1);
    
    // 这里必须只打印“customerId或customerName”这样已经加载的属性才能看到延迟加载的效果
    // 这里如果打印Customer对象整体则看不到效果
    System.out.println("customer = " + customer.getCustomerName());
    
    // 先指定具体的时间单位,然后再让线程睡一会儿
    TimeUnit.SECONDS.sleep(5);
    
    List<Order> orderList = customer.getOrderList();
    
    for (Order order : orderList) {
        System.out.println("order = " + order);
    }
}

效果:刚开始先查询Customer本身,需要用到OrderList的时候才发送SQL语句去查询

DEBUG 11-30 11:25:31,127 ==>  Preparing: select customer_id,customer_name from t_customer where customer_id=?   (BaseJdbcLogger.java:145) 
DEBUG 11-30 11:25:31,193 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 11-30 11:25:31,314 <==      Total: 1  (BaseJdbcLogger.java:145) 
customer = c01
DEBUG 11-30 11:25:36,316 ==>  Preparing: select order_id,order_name from t_order where customer_id=?   (BaseJdbcLogger.java:145) 
DEBUG 11-30 11:25:36,316 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 11-30 11:25:36,321 <==      Total: 3  (BaseJdbcLogger.java:145) 
order = Order{orderId=1, orderName='o1'}
order = Order{orderId=2, orderName='o2'}
order = Order{orderId=3, orderName='o3'}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

git克隆/拉取报错过早的文件结束符(EOF)的原因及解决

近期使用git拉取仓库的时候&#xff0c;拉取了好几次都不行&#xff0c;总是反馈说过早的文件结束符 总是这样&#xff0c;当然我的报错信息并没有描述完整&#xff0c;因为在我检索此类问题的时候&#xff0c;我发现有好多种所谓的过早的文件结束符这样的报错&#xff0c;但是…

机器学习实验报告——EM算法

目录 一、算法介绍 1.1算法背景 1.2算法引入 1.3算法假设 1.4算法原理 1.5算法步骤 二、算法公式推导 2.1数学基础 2.2EM算法推导 三、算法实现 3.1关于EM聚类 3.2EM工具包的使用 3.3 实例测试 四、算法讨论 4.1EM算法的优缺点 4.2EM算法的应用 4.3对于EM算法…

RT Thread Stdio生成STM32L431RCT6无法启动问题

一、问题现象 使用RT thread Stdio生成STM32L431RCT6工程后&#xff0c;编译下载完成后系统无法启动&#xff0c;无法仿真debug&#xff1b; 二、问题原因 如果当前使用的芯片支持包版本为0.2.3&#xff0c;可能是这个版本问题&#xff0c;目前测试0.2.3存在问题&#xff0c…

【51单片机】外部中断

0、前言 参考&#xff1a;普中 51 单片机开发攻略 第16章 及17章 1、硬件 2、软件 #include <reg52.h> #include <intrins.h> #include "delayms.h"typedef unsigned char u8; typedef unsigned int u16;sbit led P2^0; sbit key3 P3^2;//外部中断…

晨控CK-FR03-EC与欧姆龙NX系列EtherCAT通讯连接说明手册

晨控CK-FR03-EC与欧姆龙NX系列EtherCAT通讯连接说明手册 晨控CK-FR03-EC是一款基于射频识别技术的高频RFID标签读卡器&#xff0c;读卡器工作频率为13.56MHZ&#xff0c;支持对I-CODE 2、I-CODE SLI等符合ISO15693国际标准协议格式标签的读取。 读卡器同时支持标准工业通讯协…

机器学习周记(第二十六周:文献阅读-DPGCN)2024.1.15~2024.1.21

目录 摘要 ABSTRACT 1 论文信息 1.1 论文标题 1.2 论文摘要 1.3 论文背景 2 论文模型 2.1 问题描述 2.2 论文模型 2.2.1 时间感知离散图结构估计&#xff08;Time-aware Discrete Graph Structure Estimation Module&#xff0c;TADG Module&#xff09; 2.2.2 时间…

HNU-数据挖掘-实验2-数据降维与可视化

数据挖掘课程实验实验2 数据降维与可视化 计科210X 甘晴void 202108010XXX 文章目录 数据挖掘课程实验<br>实验2 数据降维与可视化实验背景实验目标实验数据集说明实验参考步骤实验过程1.对数据进行初步降维2.使用无监督数据降维方法&#xff0c;比如PCA&#xff0c;I…

网络要素服务(WFS)详解

文章目录 1. 概述2. GetCapabilities3. DescribeFeatureType4. GetFeature4.1 Get访问方式4.2 Post访问方式 5. Transaction5.1 Insert5.2 Replace5.3 Update5.4 Delete 6 注意事项 1. 概述 前置文章&#xff1a; 地图服务器GeoServer的安装与配置 GeoServer发布地图服务&#…

外汇天眼:每一个骗局的背后,可能是倾家荡产!

在网络科技还没有发达的以前&#xff0c;骗子主要通过线下揽客的方式推荐各类虚假的投资理财项目&#xff0c;有的甚至打着专门的理财咨询机构吸引了一大批新手投资者。在当时&#xff0c;外汇投资还不为多数人知道&#xff0c;随便忽悠“高利益保本”就有投资者上当受骗。 现如…

LINUX常用工具之sudo权限控制

一、Sudo基本介绍 sudo是Linux 中用于允许特定用户以超级用户或其他特权用户的身份执行特定的命令或任务。sudo 提供了一种安全的方法&#xff0c;使用户能够临时获取额外的权限&#xff0c;而不需要以完全超级用户的身份登录系统。sudo也可以用了设置黑名单命令清单&#xff…

多列匹配,根据对应状态、排序字段

多列匹配&#xff0c;根据对应状态、排序字段 数据&#xff1a; 查询:

Golang leetcode28 找出字符串中第一个匹配项的下标 KMP算法详解

文章目录 找出字符串中第一个匹配项的下标 leetcode28 串的模式匹配问题暴力求解使用KMP模式匹配算法KMP算法简述 KMP算法的代码实现 找出字符串中第一个匹配项的下标 leetcode28 串的模式匹配问题 暴力求解 func strStr(haystack string, needle string) int { L : len(need…

大模型笔记【3】 gem5 运行模型框架LLama

一 LLama.cpp LLama.cpp 支持x86&#xff0c;arm&#xff0c;gpu的编译。 1. github 下载llama.cpp https://github.com/ggerganov/llama.cpp.git 2. gem5支持arm架构比较好&#xff0c;所以我们使用编译LLama.cpp。 以下是我对Makefile的修改 开始编译&#xff1a; make UNAME…

用pandas实现用前一行的excel的值填充后一行

今天接到一份数据需要分析&#xff0c;数据在一个excel文件里&#xff0c;内容大概形式如下&#xff1a; 后面空的格子里的值就是默认是前面的非空的值&#xff0c;由于数据分析的需要需要对重复的数据进行去重&#xff0c;去重就需要把控的cell的值补上&#xff0c;然后根据几…

2024 前端高频面试题之 JS 篇

JS 篇&#xff08;持续更新中&#xff09; 1、什么是原型、原型链&#xff1f;2、什么是继承&#xff1f;说一说有哪些&#xff1f;继承组合的原理及优点&#xff1f;3、new 操作符具体干了什么&#xff1f;4、js 有哪些方法改变 this 指向&#xff1f;5、bind 有哪些实现的注意…

时空预测网络ST-Resnet 代码复现

ST-ResNet&#xff08;Spatio-Temporal Residual Network&#xff09;是一种用于处理时空数据的深度学习模型&#xff0c;特别适用于视频、时间序列等具有时空结构的数据。下面是一个简单的使用PyTorch搭建ST-ResNet的示例代码。请注意&#xff0c;这只是一个基本的示例&#x…

一文了解国密算法SSL证书

国密算法是中国国家密码管理局发布的一组密码算法标准&#xff0c;用于替代国际上的一些加密算法。在SSL证书中&#xff0c;使用国密算法的证书通常称为"国密SSL证书"。 国密SSL证书与传统的SSL证书在加密算法上有所不同。传统SSL证书通常使用的是RSA或者ECC&#xf…

QQ失效的图片怎么恢复?这3种方法送给大家!

在我们使用QQ时&#xff0c;难免会遇到QQ图片失效的情况。或许是因为误删了聊天记录&#xff0c;又或许是因为没有及时保存而导致失效。 那么&#xff0c;面对这些失效的图片&#xff0c;我们该如何恢复呢&#xff1f;qq失效的图片怎么恢复&#xff1f;今天&#xff0c;小编将…

一起读《奔跑吧Linux内核(第2版)卷1:基础架构》- 了解kmalloc、vmalloc、malloc

大家好&#xff0c;我是硬核王同学&#xff0c;最近在做免费的嵌入式知识分享&#xff0c;帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作&#xff01; 移步飞书获得更好阅读体验&#xff1a; Docs Hello&#xff0c;大家好我是硬核王同学&#xff0c;是一名刚刚工作一年…

开源无代码应用程序生成器Saltcorn

什么是 Saltcorn &#xff1f; Saltcorn 是一个无需编写任何代码即可构建数据库 Web 应用程序的平台。它配备了一个吸睛的仪表板&#xff0c;丰富的生态系统、视图生成器以及支持主题的界面&#xff0c;使用直观的点击、拖放用户界面来构建整个应用程序。 软件的特点&#xff1…