Mybatis之关联

news2024/9/30 19:30:18

一、一对多关联

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'}

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

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

相关文章

翻译: LLM构建 GitHub 提交记录的聊天机器人一 使用 Timescale Vector、pgvector 和 LlamaIndex

1. 检索增强生成 &#xff08;RAG Retrieval Augmented Generation&#xff09; 检索增强生成 &#xff08;RAG Retrieval Augmented Generation&#xff09; 对于增强应用程序开发中的大型语言模型 &#xff08;LLM&#xff09; 至关重要。它用外部数据源补充 LLM&#xff0c…

ChatGPT关键技术、发展方向与应用前景

源自&#xff1a;中国指挥与控制学会 作者&#xff1a;黄海涛 田虎 郑晓龙 曾大军 一、GPT类模型技术发展路径 图1 GPT类模型推出时间线1&#xff0c;2 二、ChatGPT模型的主要技术手段 图2 GPT类模型采用的Transformer解码器模型结构 图3 RLHF迭代训练过程真正推动ChatGPT模型…

物联网协议Coap之C#基于Mozi的CoapServer实现解析

目录 前言 一、C#的Coap Server实现 1、CoapServer相关类 2、主要类解析 3、资源控制器定义 4、ResourceManager管理器 二、CoapServer生命周期 1、Server创建代码 2、服务端创建 3、绑定endpoint 4、准备接收请求 总结 前言 在之前的关于物联网协议的介绍中&#…

ELK日志分析

目录 1.ELK概述 ELK简述 ElasticSearch Kiabana Logstash 可添加其他的组件 Filebeat filebeat结合logstash带来好处 缓存/消息队列&#xff08;redis、kafka、RabbitMQ等&#xff09; Fluentd ELK的好处 完整日志系统基本特征 ELK的工作原理 2.ELK Elasticsearc…

Git提交 ssh: connect to host github.com port 22: Connection timed out解决方案

你们好&#xff0c;我是金金金。 场景 之前都是好好的&#xff0c;不知道今天为什么提交代码就这样了 排查 根据英文可以看出&#xff0c;ssh端口号被拒绝了&#xff0c;22号端口不行&#xff0c;那就换一个端口 造成error的原因 ssh端口被拒绝 解决 找到.ssh文件&#xff…

Producer源码解读

Producer源码解读 在 Kafka 中, 我们把产生消息的一方称为 Producer 即 生产者, 它是 Kafka 的核心组件之一, 也是消息的来源所在。它的主要功能是将客户端的请求打包封装发送到 kafka 集群的某个 Topic 的某个分区上。那么这些生产者产生的消息是怎么传到 Kafka 服务端的呢&a…

Linux系统三剑客之grep和正则表达式的介绍(一)

1.正则表达式 目录 1.正则表达式 1.什么是正则表达式 &#xff1f; 2.正则表达式的使用场景 3.正则表达式字符表示 4.它们之间的区别 2.grep命令 作用&#xff1a; 语法&#xff1a; 说明&#xff1a; 选项&#xff1a;options 重点 实例 3.后面的下次再更新。 …

hanlp,pkuseg,jieba,cutword分词实践

总结&#xff1a;只有jieba,cutword,baidu lac成功将色盲色弱成功分对,这两个库字典应该是最全的 hanlp[持续更新中] https://github.com/hankcs/HanLP/blob/doc-zh/plugins/hanlp_demo/hanlp_demo/zh/tok_stl.ipynb import hanlp # hanlp.pretrained.tok.ALL # 语种见名称最…

统计学-R语言-6.3

文章目录 前言总体方差的区间估计总体方差的区间估计(一个总体方差的估计)总体方差的区间估计(两个总体方差比的估计) 总结 前言 本篇文章是最后一个介绍参数估计的章节。 总体方差的区间估计 研究一个总体时&#xff0c;推断总体方差 使用的统计量为样本方差 。研究两个总体…

MacOS受欢迎的数据库开发工具 Navicat Premium 15 中文版

Navicat Premium 15 Mac是一款数据库管理工具&#xff0c;提供了一个全面的解决方案&#xff0c;用于连接、管理和维护各种数据库系统。以下是Navicat Premium 15 Mac的一些主要功能和特点&#xff1a; 软件下载&#xff1a;Navicat Premium 15 中文版下载 多平台支持&#xff…

代码、课程、教学的一些思考-2024

1 代码、算法、艺术品 1.1 代码 最典型的C代码示例。 以下是一个简单的C代码示例&#xff0c;它打印出“Hello, World!”&#xff1a; #include <iostream> int main() { std::cout << "Hello, World!"; return 0; } 这段代码定义了一个程序&a…

2024年美国各州即将生效的新隐私保护法(上)

2024年美国各州即将生效的新隐私保护法&#xff08;上&#xff09; 文章目录 2024年美国各州即将生效的新隐私保护法&#xff08;上&#xff09;前言一、2023年隐私保护法开始生效的五个州二、2023年通过了新的隐私保护法的八个州三、2024年确定截止的州及法律法规&#xff08;…

Python GUI 新手入门教程:轻松构建图形用户界面

Python 凭借其简单性和多功能性&#xff0c;已经成为最流行的编程语言之一。被广泛应用于从 web 开发到数据科学的各个领域。 在本教程中&#xff0c;我们将探索用于创建图形用户界面&#xff08;GUIs&#xff09;的 Python 内置库&#xff1a; Tkinter&#xff1a;无论你是初…

深入学习卷积神经网络(CNN)的原理知识

在深度学习领域中&#xff0c;已经经过验证的成熟算法&#xff0c;目前主要有深度卷积网络&#xff08;DNN&#xff09;和递归网络&#xff08;RNN&#xff09;&#xff0c;在图像识别&#xff0c;视频识别&#xff0c;语音识别领域取得了巨大的成功&#xff0c;正是由于这些成…

gitlab 命令执行漏洞(CVE-2022-2992)

1.漏洞影响版本 GitLab CE/EE 中的一个漏洞影响从 11.10 开始到 15.1.6 之前的所有版本、从 15.2 开始到 15.2.4 之前的所有版本、从 15.3 开始到 15.3.2 之前的所有版本。允许经过身份验证的用户通过从 GitHub API 端点导入实现远程代码执行。 查看 gitlab 版本。(登录后才能…

keil logic analyzer使用

DARMSTM.DLL--- -pSTM32F103VC ---- TRAMSTM.DLL ------ -pSTM32F103VC 然后点击DEBUG按钮 用上面的名称USART1_SR 点击STUP 不同的引脚&#xff0c;用不同的名称&#xff0c;通过放大缩小来查看波形。当前串口用的是USART1_SR&#xff0c;只能用这个名称&#xff0c;…

海思刷机注意事项

目录 为什么写这个文档海思SOC刷机原理1.串口缓冲区关闭2.IP地址自动更改导致无法烧录3.烧录完成后找不到根文件系统4.由于电源设计不合理导致无法烧录 为什么写这个文档 海思SOC刷机时,偶然会遇到奇奇怪怪的问题,会刷机不上.现在总结一下. 海思SOC刷机原理 如果没有任何程序…

VUE--组件通信(非父子)

一、非父子通信 --- event bus 事件总线 作用&#xff1a;非父子组件之间进行简易的消息传递 步骤&#xff1a; 1、创建一个都能访问到的事件总线&#xff08;空vue实例&#xff09;--- utils/EventBus.js import Vue from vue export default new Vue({}) 2、 接收方&…

day5:IO多路复用

思维导图 TCP并发服务器的IO复用poll函数实现 #include <head.h> #define SER_PORT 8888 #define SER_IP "192.168.232.133" int main(int argc, const char *argv[]) {int sfdsocket(AF_INET,SOCK_STREAM,0);if(sfd-1){perror("sfd error:");retur…

【正点原子STM32】Cortex-M系列介绍(ARM、Cortex、DMIPS/MHz和CoreMark/MHz*)

一、ARM公司 二、Cortex内核分类及特征 三、Cortex-M3/4/7介绍 四、总结 ARM官网 ARM开发者官网 CoreMark分数 一、ARM公司 ARM架构特点 ARM&#xff08;Advanced RISC Machine&#xff09;架构是一种RISC&#xff08;Reduced Instruction Set Computing&#xff09;架构&…