大白话帮你理解Mybatis中的高级映射(一对一、一对多、多对多)

一、 概述

可能很多小伙伴在学习mybatis中高级映射,看到一对一、一对多、多对多脑子一片混论,这都是些什么乱七八糟

因此在学习这部分内容是都是一路懵圈。下面我将自己的领悟分享给大家,不喜勿喷哈,文章不合适的地方欢迎大家共同商讨

二、什么是映射

大家都知道Myabtis是一个不完全的ORM(对象-关系映射)框架,那什么是对象什么是映射呢?
简单来说,就是面向对象的思想。大家既然能学到mybatis想必就不用我多说面向对象是什么了。高级映射都是在多表操作中使用的,在mybatis中把对象之间使用statement进行了关联,数据库中使用外键将数据表之间进行关联,从而完成某个需求。

举个例子:网购的时候,我可以下单买东西,一个订单里我可以购买多个商品,我还可以下很多订单。

我就是一个对象,订单和商品是对象,订单详情也是一个对象,他们之间关系就是通过statement进行关联映射的。

三、理解高级映射

继续用上面的例子

3.1 一对一(resultMap)

我可以创建多个订单,但是每一个订单都由唯一一个用户创建的,因此就可以在用户表里选择一个主键字段作为订单表的外键,在订单表的持久类中定义一个用户类的属性

在这里插入图片描述
映射思路:

  1. 使用resultMap将查询结果中的订单信息映射到Orders对象中,在orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中。

订单持久类:

public class Orders {
    private Integer id;

    private Integer userId;

    private String number;

    private Date createtime;

    private String note;
    
    //用户信息
    private User user;

在Mapper文件中使用association子标签进行关联

<!--订单关联用户使用resultMap一对一查询-->
    <select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap">
        SELECT
		orders.*,
		USER.username,
		USER.sex,
		USER.address
		FROM
		orders,
		USER
		WHERE orders.user_id = user.id
    </select>
    <resultMap id="OrdersUserResultMap" type="com.zg.ssm.po.OrdersCustom">
    	<!-- 配置映射的订单信息 -->
		<!-- id:指定查询列中的唯一标识,订单信息的中的唯 一标识,如果有多个列组成唯一标识,配置多个id
			column:订单信息的唯一标识列
			property:订单信息的唯一标识列所映射到Orders中哪个属性
		  -->
        <id property="id" column="id"></id>
        <result property="userId" column="user_id"></result>
        <result property="createtime" column="createtime"></result>
        <result property="note" column="note"></result>
        <result property="number" column="number"></result>
        <!-- 配置映射的关联的用户信息 -->
		<!-- association:用于映射关联查询单个对象的信息
		property:要将关联查询的用户信息映射到Orders中哪个属性
		 -->
        <association property="user" javaType="com.zg.ssm.po.User">
        	<!-- id:关联查询用户的唯一标识
			column:指定唯一标识用户信息的列
			property:映射到user的哪个属性
			 -->
            <id property="id" column="id"></id>
            <result property="userName" column="userName"></result>
            <result property="address" column="address"></result>
            <result property="sex" column="sex"></result>
        </association>
    </resultMap>

3.2 一对多

一个订单可能会下多个商品有很多的订单详情,这时就需要在订单表Orders中添加订单详情Ordersdatil属性,并且以集合方式定义,
在这里插入图片描述

public class Orders {
    private Integer id;

    private Integer userId;

    private String number;

    private Date createtime;

    private String note;
    
    //用户信息
    private User user;
    
    //订单明细
    private List<Orderdetail> orderdetails;

在Mapper文件中使用****子标签进行关联

<!-- 查询订单关联查询用户及订单明细,使用resultmap -->
	<select id="findOrdersAndOrderDetailResultMap" resultMap="OrdersAndOrderDetailResultMap">
		SELECT 
		  orders.*,
		  USER.username,
		  USER.sex,
		  USER.address,
		  orderdetail.id orderdetail_id,
		  orderdetail.items_id,
		  orderdetail.items_num,
		  orderdetail.orders_id
		FROM
		  orders,
		  USER,
		  orderdetail
		WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id
	</select>
	<!-- 订单及订单明细的resultMap
	使用extends继承,不用在中配置订单信息和用户信息的映射
	 -->
	<resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersAndOrderDetailResultMap" extends="OrdersUserResultMap">
		<!-- 订单信息 -->
		<!-- 用户信息 -->
		<!-- 使用extends继承,不用在中配置订单信息和用户信息的映射 -->
		
		
		<!-- 订单明细信息
		一个订单关联查询出了多条明细,要使用collection进行映射
		collection:对关联查询到多条记录映射到集合对象中
		property:将关联查询到多条记录映射到cn.itcast.mybatis.po.Orders哪个属性
		ofType:指定映射到list集合属性中pojo的类型
		 -->
		 <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
		 	<!-- id:订单明细唯 一标识
		 	property:要将订单明细的唯 一标识 映射到cn.itcast.mybatis.po.Orderdetail的哪个属性
		 	  -->
		 	<id column="orderdetail_id" property="id"/>
		 	<result column="items_id" property="itemsId"/>
		 	<result column="items_num" property="itemsNum"/>
		 	<result column="orders_id" property="ordersId"/>
		 </collection>
	</resultMap>

3.3多对多

一个用户可以购买多个商品,一个商品可以由多个用户购买,由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关联表:orders、orderdetail、items。

映射思路:

  1. 将用户信息映射到user中。
  2. 在user类中添加订单列表属性List《Orders》 orderslist,将用户创建的订单映射到orderslist
  3. 在Orders中添加订单明细列表属性List《OrderDetail》orderdetials,将订单的明细映射到orderdetials
  4. 在OrderDetail中添加Items属性,将订单明细所对应的商品映射到Items
    在这里插入图片描述
<!-- 查询用户及购买的商品信息,使用resultmap -->
	<select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap">
		SELECT 
		  orders.*,
		  USER.username,
		  USER.sex,
		  USER.address,
		  orderdetail.id orderdetail_id,
		  orderdetail.items_id,
		  orderdetail.items_num,
		  orderdetail.orders_id,
		  items.name items_name,
		  items.detail items_detail,
		  items.price items_price
		FROM
		  orders,
		  USER,
		  orderdetail,
		  items
		WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id AND orderdetail.items_id = items.id
	</select>
<!-- 查询用户及购买的商品 -->
	<resultMap type="cn.itcast.mybatis.po.User" id="UserAndItemsResultMap">
		<!-- 用户信息 -->
		<id column="user_id" property="id"/>
		<result column="username" property="username"/>
		<result column="sex" property="sex"/>
		<result column="address" property="address"/>
		
		<!-- 订单信息
		一个用户对应多个订单,使用collection映射
		 -->
		 <collection property="ordersList" ofType="cn.itcast.mybatis.po.Orders">
		 	<id column="id" property="id"/>
		 	<result column="user_id" property="userId"/>
			<result column="number" property="number"/>
			<result column="createtime" property="createtime"/>
			<result column="note" property="note"/>
			
			 <!-- 订单明细
		 一个订单包括 多个明细
		  -->
		  	<collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
		  			<id column="orderdetail_id" property="id"/>
				 	<result column="items_id" property="itemsId"/>
				 	<result column="items_num" property="itemsNum"/>
				 	<result column="orders_id" property="ordersId"/>
				 	
				 	<!-- 商品信息
		  	一个订单明细对应一个商品
		  	 -->
		  	 	<association property="items" javaType="cn.itcast.mybatis.po.Items">
		  	 		<id column="items_id" property="id"/>
		  	 		<result column="items_name" property="name"/>
		  	 		<result column="items_detail" property="detail"/>
		  	 		<result column="items_price" property="price"/>
		  	 	</association>
		  	</collection>
		 </collection>

此图可根据需求定义属性

四、总结

resultType:
作用:
将查询结果按照sql列名pojo属性名一致性映射到pojo中。
场合:
常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可。

resultMap:
使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。

association:
作用:
将关联查询信息映射到一个pojo对象中。
场合:
为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中,比如:查询订单及关联用户信息。
使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需要选择使用resultType还是resultMap。

collection:
作用:
将关联查询信息映射到一个list集合中。
场合:
为了方便查询遍历关联信息可以使用collection将关联信息映射到list集合中,比如:查询用户权限范围模块及模块下的菜单,可使用collection将模块映射到模块list中,将菜单列表映射到模块对象的菜单list属性中,这样的作的目的也是方便对查询结果集进行遍历查询。

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嗨!大白话讲解Promise(一)啊!好的,我来给你解释一下。 首先,我们要知道Promise是JavaScript处理异步操作的一种方式。异步操作就是那些不会立即返回结果的操作,比如从服务器上获取数据或者执行耗时的任务。在以前,我们通常使用回调函数来处理异步操作,但是回调函数的嵌套会导致代码变得难以阅读和维护。而Promise就是为了解决这个问题而出现的。 Promise可以被看作是一种代表了未来结果的对象。它有三个状态:pending(进行)、fulfilled(已成功)和rejected(已失败)。当一个异步操作开始执行时,它的状态是pending;当操作成功完成时,它的状态变为fulfilled,并且会返回一个值;当操作失败时,它的状态变为rejected,并且会返回一个错误。 使用Promise的好处是可以更清晰地编写异步代码。我们可以通过调用Promise的then()方法来处理成功的情况,通过调用catch()方法来处理失败的情况。这样就避免了回调函数的嵌套,代码更加易读和易于维护。 当我们创建一个Promise对象时,我们需要传入一个执行器函数,这个函数会立即执行。执行器函数接受两个参数:resolve和reject。在执行器函数,我们可以执行异步操作,并在合适的时候调用resolve或reject来改变Promise的状态。 我来举个例子来说明一下: ```javascript const promise = new Promise((resolve, reject) => { // 这里可以执行异步操作 // 如果操作成功,调用resolve并传入结果 // 如果操作失败,调用reject并传入错误 }); promise.then((result) => { // 处理操作成功的情况 }).catch((error) => { // 处理操作失败的情况 }); ``` 这就是Promise的简单介绍,望能到你!如果你还有其他问题,尽管问吧!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值