mybatis多字段嵌套映射

本文介绍了如何通过MyBatis的resultMap进行多字段映射,解决前端对考勤管理临时排班数据的整理需求,将相同userId和scheduledDate的计划模板进行有效合并,提升数据展示的友好性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可直接翻到最后面看原理部分~

应用场景:
最近在做考勤管理的临时排班,需要根据用户id查询临时排班表记录,临时排班可以嵌套多个计划模版;

mybatis的xml文件如下:

<select id="select" parameterType="userTempPlan" resultMap="userTempPlanMap">
    select 
        user_temp_plan.user_id,
	user_temp_plan.scheduled_date,
	schclass.start_time schclass_start_time,
	schclass.end_time schclass_end_time,
	schclass.name schclass_name
    from 
	user_temp_plan,
	schedule_class
    <where>
	user_temp_plan.schclass_id = schclass.id
	<!-- 根据userId查询 -->
	<if test="userId!=null and userId != ''">
            and user_temp_plan.user_id = #{userId}
	</if>
    </where>
</select>

<resultMap id="userTempPlanMap" type="userTempPlan" extends="BaseResultMap">
    <collection property="scheduleClassList" fetchType="lazy" columnPrefix="schclass_" resultMap="com.xxx.dao.ScheduleClassMapper.BaseResultMap" />
</resultMap>

查询之后的结果如下:

{
  "id":"id1"
  "userId": "userId1",
  "scheduledDate": "2019-10-01",
  "scheduleClassList": [
        {
	  "name": "新建时间段11",
	  "startTime": "09:00",
	  "endTime": "12:00"
	},
	{
	  "name": "新建时间段12",
	  "startTime": "14:00",
	  "endTime": "18:00"
	}
  ]
},
{
  "id":"id2"
  "userId": "userId1",
  "scheduledDate": "2019-10-01",
  "scheduleClassList": [
	{
	  "name": "新建时间段2",
	  "startTime": "17:00",
	  "endTime": "20:59"
	}
  ]
}

前端人员说,这个数据不友好,能不能把时间段相同的嵌套在一起,我想起mybatis好像可以根据字段进行嵌套映射,就试了一下:
这里需要根据userIdscheduledDate进行嵌套映射,如果数据中userIdscheduledDate相同,我们就把查询出来的计划模版进行嵌套;

查询的sql语句不变,但resultMap需要调整一下:

<resultMap id="userTempPlanMap" type="userTempPlan">
    <!-- 根据user_id,scheduled_date进行嵌套映射 -->
    <id column="user_id" jdbcType="VARCHAR" property="userId" />
    <id column="scheduled_date" jdbcType="DATE" property="scheduledDate" />
    <collection property="scheduleClassList" fetchType="lazy" columnPrefix="schclass_" resultMap="com.xxx.dao.ScheduleClassMapper.BaseResultMap" />
</resultMap>

查询之后的结果如下:

{
  "userId": "userId1",
  "scheduledDate": "2019-10-01",
  "scheduleClassList": [
	{
	  "name": "新建时间段11",
	  "startTime": "09:00",
	  "endTime": "12:00"
	},
	{
	  "name": "新建时间段12",
	  "startTime": "14:00",
	  "endTime": "18:00"
	},
	{
	  "name": "新建时间段2",
	  "startTime": "17:00",
	  "endTime": "20:59"
	}
  ]
}

这个就是前端想要的数据了。

原理

MyBatis在处理结果的时候,会判断结果是否相同,如果是相同的结果,则只会保留第一个结果,所以这个问题的关键点就是MyBatis如何判断结果是否相同。

MyBatis判断结果是否相同时,最简单的情况就是在映射配置中至少有一个id标签,在userMap中配置如下。
<id property=nid" column="id />

我们对id(构造方法中为idArg)的理解一般是,它配置的字段为表的主键(联合主键时可以配置多个id标签),因为MyBatis的resultMap只用于配置结果如何映射,并不知道这个表具体如何。id的唯一作用就是在嵌套的映射配置时判断数据是否相同,当配置id标签时,MyBatis只需要逐条比较所有数据中id标签配置的字段值是否相同即可。在配置嵌套结果查询时,配置id标签可以提高处理效率。( 如果没配置id标签的话会比对所有字段)

所以我们配置两个<id column="id" property="id" />即可实现多字段映射。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值