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_idwhere t_customer.customer_id=#{customerId}</select>

测试:

   @Testpublic 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_idwhere order_id=#{orderId};</select>

测试:

   @Testpublic  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_idwhere 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,namefrom books,category,category_bookWHERE books.id=category_book.book_idand category_book.category_id=category.category_idand 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_idfrom  books,category,category_bookWHERE books.id=category_book.book_idand category_book.category_id=category.category_idand 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.hqwc.cn/news/412607.html

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

相关文章

burp靶场--ssrf

burp靶场–ssrf 1.什么是ssrf 服务器端请求伪造是一种 Web 安全漏洞&#xff0c;允许攻击者导致服务器端应用程序向非预期位置发出请求。 在典型的 SSRF 攻击中&#xff0c;攻击者可能会导致服务器连接到组织基础设施内的仅供内部使用的服务。在其他情况下&#xff0c;他们可…

LeetCode 104. 二叉树的最大深度

104. 二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1…

SpringBoot中整合MybatisPlus快速实现Mysql增删改查和条件构造器

场景 Mybatis-Plus(简称MP)是一个Mybatis的增强工具&#xff0c;只是在Mybatis的基础上做了增强却不做改变&#xff0c;MyBatis-Plus支持所有Mybatis原生的特性&#xff0c; 所以引入Mybatis-Plus不会对现有的Mybatis构架产生任何影响。MyBatis 增强工具包&#xff0c;简化 C…

短视频代运营抖音项目规划管理计划模板

【干货资料持续更新&#xff0c;以防走丢】 短视频代运营抖音项目规划管理计划模板 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 短视频代运营模板&#xff08;完整资料包含以下内容&#xff09; 目录 具体的表格设计和内容可能因不同的情况和需求而有所变…

重拾计网-第一弹

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾计算机网络 &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错…

BIOS知识枝桠——RAID 磁盘阵列

文章目录 前言一、RAID介绍二、RAID等级分类1.RAID02.RAID13.RAID24.RAID3和RAID45.RAID5和RAID66.RAID77.RAID10 BIOS下组建RAID 前言 假设存在多块磁盘&#xff0c;如果不组建阵列&#xff0c;磁盘与磁盘之间是没有任何关系的。磁盘A和B&#xff0c;放在A中的文件与B磁盘没有…

k8s---对外服务 ingress

目录 目录 目录 ingress与service ingress的组成 ingress-controller&#xff1a; ingress暴露服务的方式 2.方式二&#xff1a;DaemonSethostnetworknodeSelector DaemonSethostnetworknodeSelector如何实现 3.deploymentNodePort&#xff1a; 虚拟主机的方式实现http代…

软件总体测试计划书

软件项目支撑文件—总体测试计划书 1.测试工作总体流程 2.计划、用例阶段流程图 3.代码测试 4.系统测试 5.非功能测试 6.测试策略 7.测试方法

ES 之索引和文档

本文主要介绍ES中的数据组成结构单元。 一、文档(Document) 1、概念 ES的数据存储单元是面向文档的&#xff0c;文档是所有数据存储&#xff0c;搜索的最小单元。 你可以把ES中的文档对应成mysql中的一条条数据记录。到时候你存进ES的数据就是一个个文档。 文档存入ES是序列…

redis数据安全(一)数据持久化

一、Redis数据安全措施: 1、将数据持久化至硬盘 2、将数据复制至其他机器&#xff1b; 复制是在数据持久化的基础上进行的。 二、将数据持久化至硬盘 1、介绍&#xff1a;Redis是一个基于内存的数据库&#xff0c;它的数据是存放在内存中&#xff0c;内存有个问题就是关闭…

首次公开发声,OpenAI CEO 奥特曼回忆“宫斗门”丨 RTE 开发者日报 Vol.129

开发者朋友们大家好&#xff1a; 这里是「RTE 开发者日报」&#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…

linux 更新镜像源

打开终端&#xff0c;备份一下旧的 源 文件&#xff0c;以防万一 cd /etc/apt/ ls sudo cp sources.list sources.list.bak ls然后打开清华大学开源软件镜像站 搜索一下你的linux发行版本&#xff0c;我这里是ubuntu发行版本 点击这个上面图中的问号 查看一下自己的版本号&a…