MyBatis用嵌套ResultMap实现一对多映射

背景

面对复杂的项目,有些对象的属性是集合类型。该集合类型是另一个表中的实体内容。

我们知道,MyBatis可以很方便地把SQL select出来的数据直接映射为对象的属性,把对象取出来。

但是。简面对集合类型的数据,可就麻烦多了。

例子:

以下面的场景介绍

有一种资源 简称:模板一个模板有多个使用范围每个使用范围有 一个 使用主体集合属性 和 一个 使用人集合属性。

翻译代码如下:

// 资源
public class CategoryBean  {
	private Long id;
	private String name; 		// 分类名称
	private List<CategoryScope> scopes; // 发起范围
}
// 使用范围
public class CategoryScope {
	
	private Long id;
	private Long categoryId;	// 资源id
    // 使用主体(指定组织使用,所有人可使用)
	private List<CategorySponsor> sponsors;
    // 使用人(人、角色、组织)
	private List<CategorySender> senders;
}
// 使用主体
public class CategorySponsor {
	private Long scopeId;		// 所属范围id
	private String type;	// 使用主体类型
}
// 使用人
public class CategorySender{
	private Long scopeId;		// 所属范围id
	private String userType;	// 使用人类型
}

介绍两种方法使用

1、嵌套ResultMap

第一步按照 上面的代码构建 resultMap 

Mapper文件

<resultMap type="CategoryBean" id="categoryMap">
		<id property="id" column="id"/>
		<collection property="scopes" javaType="ArrayList" ofType="CategoryScopeMap" column="id" select="scopes"/>
</resultMap>

<resultMap type="CategoryScope" id="CategoryScopeMap">
        <!-- id 属性是CategoryScope的字段属性  -->
		<id property="id" column="id"/>
		<collection property="sponsors" javaType="ArrayList" column="id" ofType="CategorySponsor" select="sponsors" />
		<collection property="senders" javaType="ArrayList"  column="id" ofType="CategorySender" select="senders" />
</resultMap>

第二步 写上 对应的查询方法

<!-- 这是主要的查询方法 -->
<select id="mainSelect" resultMap="openCategoryMap">
		SELECT c.*
		FROM CATEGORY c where id = #{id}
</select>

<!-- scopes 的 查询方法 id的属性 来自 CategoryBean 的 property="id" -->
<select id="scopes" resultMap="CategoryScopeMap">
		SELECT scope.* FROM CATEGORY_SCOPE scope WHERE scope.categoryId = #{id}
</select>

<!-- sponsors 的 查询方法 id的属性 来自 CategoryScope 的 property="id" -->
<select id="sponsors" resultType="CategorySponsor">
		SELECT sponsor.* FROM CATEGORY_SPONSOR sponsor  WHERE sponsor.scopeId = #{id}
</select>

<!-- senders 的 查询方法 id的属性 来自 CategoryScope 的 property="id" -->
<select id="senders" resultType="CategorySender">
		SELECT sender.*  FROM CATEGORY_SENDER sender WHERE sender.scopeId = #{id}
</select>

第三步

得出结果 就是你想要的

2、autoMapping

这个方法采用的是 前缀匹配的方式. 我未进行深入研究,目前只适用于 一级嵌套。注意下面的格式。

第一步 构建总的  resultMap

<resultMap type="CategoryBean" id="categoryMap" autoMapping="true">
		<id property="id" column="id"/>
		<collection property="sponsors" javaType="ArrayList" ofType="CategorySponsor" columnPrefix="sponsor_" autoMapping="true"/>
		<collection property="senders" javaType="ArrayList" ofType="CategorySender" columnPrefix="sender_" autoMapping="true"/>
	</resultMap>
<select id="mainselect" resultMap="categoryMap">
		SELECT c.id,c.name,
			sponsor.companyId sponsor_companyId,sponsor.type sponsor_type ,
			sender.userId sender_userId , sender.userName sender_userName , sender.userType sender_userType
		FROM CATEGORY c
			INNER JOIN CATEGORY_SCOPE scope ON scope.categoryId = c.id
			LEFT JOIN CATEGORY_SPONSOR sponsor ON sponsor.scopeId = scope.id
			LEFT JOIN CATEGORY_SENDER sender ON sender.scopeId = scope.id
		WHERE c.id = #{id}
	</select>

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值