mybatis 连表查询,子查询 collection,返回 vo

1. 连表查询,子查询 collection,返回 vo

AppsService.xml 主查询

	<resultMap id="appsMap" type="com.boyia.magic.lxt.api.entity.Apps">
        <id property="id" column="id"/>
        <result property="appName" column="app_name"/>
        <result property="appType" column="app_type"/>
        <result property="appIcon" column="app_icon"/>
        <result property="appPlatform" column="app_platform"/>
        <result property="appCategoryId" column="app_category_id"/>
        <result property="appLanguage" column="app_language"/>
        <result property="appBrief" column="app_brief"/>
        <result property="appKey" column="app_key"/>
        <result property="appSecret" column="app_secret"/>
        <result property="createBy" column="create_by"/>
        <result property="createTime" column="create_time"/>
        <result property="updateBy" column="update_by"/>
        <result property="updateTime" column="update_time"/>
        <result property="status" column="status"/>
        <result property="delFlag" column="del_flag"/>
  </resultMap>
  
	<resultMap id="appVoMap" type="com.boyia.magic.lxt.api.vo.AppsVo">
		<id property="id" column="id"/>
		<result property="appName" column="app_name"/>
		<result property="appType" column="app_type"/>
		<result property="appIcon" column="app_icon"/>
		<result property="appPlatform" column="app_platform"/>
		<result property="appCategoryId" column="app_category_id"/>
		<result property="appLanguage" column="app_language"/>
		<result property="appBrief" column="app_brief"/>
		<result property="appKey" column="app_key"/>
		<result property="appSecret" column="app_secret"/>
		<result property="createBy" column="create_by"/>
		<result property="createTime" column="create_time"/>
		<result property="updateBy" column="update_by"/>
		<result property="updateTime" column="update_time"/>
		<result property="status" column="status"/>
		<result property="delFlag" column="del_flag"/>
		<!--分类名称-->
		<result property="categoryName" column="category_name"/>
		<!--分类层级名称-->
		<result property="categoryNames" column="category_names"/>
		<!--应用分组集合-->
		<collection property="groupList" ofType="com.boyia.magic.lxt.api.dto.AppGroupForListNameDto"
					select="getByAppsId" column="categoryId = id">
					<result property="articleId" column="id"/>
					<result property="articleName" column="name"/>
		</collection>

		<collection property="articleNameList" ofType="javax.long.String"
					select="getByAppsId" column="categoryId = id">
					<result property="articleName" column="name"/>
		</collection>
	</resultMap>

<select id="getByAppsId">
	SELECT
		name,
		sex
	WHERE
		article.category_id = #{categoryId}
</select>

	<!--分页查询-->
	<select id="pageByQuery" resultMap="appVoMap" resultType="com.boyia.magic.lxt.api.vo.AppsVo">
		SELECT
		  t1.id,
			t1.app_name,
			t1.app_type,
			t1.app_icon,
			t1.app_platform,
			t1.app_category_id,
			t1.app_language,
			t1.app_brief,
			t1.app_key,
			t1.app_secret,
			t1.create_by,
			t1.create_time,
			t1.update_by,
			t1.update_time,
			t1.status,
			t2.category_name,
			t2.category_names
		FROM
			lxt_platform_apps AS t1
			LEFT JOIN lxt_platform_apps_category AS t2 ON t1.app_category_id = t2.id
		WHERE
			t1.del_flag = '0'
			AND t2.del_flag = '0'
		<if test="query.appName != null and query.appName != ''">
			AND t1.app_name LIKE CONCAT(CONCAT('%', #{query.appName}), '%')
		</if>
		<if test="query.appType != null and query.appType != ''">
			AND t1.app_type = #{query.appType}
		</if>
		<if test="query.appPlatform != null and query.appPlatform != ''">
			AND t1.app_platform = #{query.appPlatform}
		</if>
		<if test="query.appCategoryId != null">
			AND t1.app_category_id = #{query.appCategoryId}
		  	OR t1.app_category_id IN ( SELECT id FROM lxt_platform_apps_category WHERE parent_ids LIKE CONCAT(CONCAT('%,',#{query.appCategoryId}),',%') )
		</if>
		<if test="query.groupId != null">
			AND t1.id IN ( SELECT apps_id FROM lxt_platform_apps_group_relation WHERE group_id = #{query.groupId} )
		</if>
		ORDER BY
			t1.create_time
		DESC
	</select>

AppsGroupMapper.java 子查询

@Mapper
public interface AppsGroupMapper extends MagicBaseMapper<AppsGroup> {

	/**
	 * 根据应用id查询分组对象列表
	 *
	 * @param id 应用id
	 * @return 应用分组对象列表
	 */
	List<AppGroupForListNameDto> getByAppsId(Long id);
}

AppsGroupMapper.xml 子查询

<mapper namespace="com.boyia.magic.lxt.mapper.AppsGroupMapper">

  <resultMap id="appsGroupMap" type="com.boyia.magic.lxt.api.entity.AppsGroup">
        <id property="id" column="id"/>
        <result property="groupName" column="group_name"/>
        <result property="rankWeight" column="rank_weight"/>
        <result property="remark" column="remark"/>
        <result property="createBy" column="create_by"/>
        <result property="createTime" column="create_time"/>
        <result property="updateBy" column="update_by"/>
        <result property="updateTime" column="update_time"/>
        <result property="status" column="status"/>
        <result property="delFlag" column="del_flag"/>
  </resultMap>

	<!--根据应用id查询分组对象列表-->
	<select id="getByAppsId" resultType="com.boyia.magic.lxt.api.dto.AppGroupForListNameDto">
		SELECT
			id,
			group_name
		FROM
			lxt_platform_apps_group
		WHERE
			id IN ( SELECT group_id FROM lxt_platform_apps_group_relation WHERE apps_id = #{id})
	</select>
</mapper>
<think>好的,我现在需要帮助用户分析他们提供的MyBatis SQL片段是否正确,特别是关于使用`pageReqVO.shardSourceIds`作为Java类的List属性是否正确的问题。首先,我需要回忆一下MyBatis中动态SQL的常见用法以及参数处理的规则。 首先,用户提供的SQL片段中有一个`<select>`标签,其中包含两个条件判断:当`pageReqVO.shardSourceIds`不为空且大小大于0时,执行包含子查询和IN条件的部分;否则直接引用另一个SQL片段。这里的`pageReqVO`应该是一个传入的参数对象,而`shardSourceIds`是该对象的一个List类型的属性。 接下来,我需要检查MyBatis中如何处理集合参数。在MyBatis的动态SQL中,当使用`<foreach>`标签遍历集合时,如果参数是一个对象中的集合属性,正确的引用方式应该是直接使用属性名,而不需要加上对象名前缀吗?比如,如果参数对象是`pageReqVO`,而属性是`shardSourceIds`,那么在`<foreach>`中应该直接使用`shardSourceIds`还是`pageReqVO.shardSourceIds`? 这里可能有个误区,因为MyBatis的参数传递机制。当传入的参数是一个对象(比如`pageReqVO`),那么在XML中引用其属性时,应该直接使用属性名,而不是通过对象.属性的方式。例如,如果方法的参数是`@Param("pageReqVO") PageReqVO pageReqVO`,那么在XML中访问`shardSourceIds`应该使用`pageReqVO.shardSourceIds`,因为参数被命名为`pageReqVO`。但如果在方法中没有使用`@Param`注解,并且参数对象直接作为参数传递,那么MyBatis会默认将对象的属性作为顶层参数访问,这时候可能需要直接使用属性名,而不是带前缀的。 不过,根据常见的实践,当参数是一个对象时,通常需要通过对象的名字来访问其属性。例如,如果方法的参数是`PageReqVO pageReqVO`,那么在动态SQL中应该使用`pageReqVO.shardSourceIds`来引用该属性。所以用户当前的写法是正确的吗? 现在看用户的代码,在`<if>`判断中,条件达式是`pageReqVO.shardSourceIds != null and pageReqVO.shardSourceIds.size > 0`,这说明用户正在检查`pageReqVO`对象的`shardSourceIds`属性是否为非空且非空列。同样,在`<foreach>`标签中,`collection`属性被设置为`pageReqVO.shardSourceIds`,这意味着MyBatis会遍历这个集合。 但是,根据MyBatis的官方文档,当使用`<foreach>`时,`collection`属性应该指定要遍历的集合名称。如果这个集合是作为参数对象的属性存在,那么正确的引用方式应该取决于参数是如何传入的。例如,如果整个参数对象被命名为`pageReqVO`(比如通过`@Param("pageReqVO")`),那么在`collection`中应该使用`pageReqVO.shardSourceIds`。如果参数对象没有命名,而是直接传递的,那么可能需要使用`list`或者`collection`,但这通常是在没有命名参数的情况下。 假设用户的方法签名是类似于这样的: ```java PageResult<TalentSharedSourcePageRespVO> getTalentSharedSourcePage(@Param("pageReqVO") TalentSharedSourcePageReqVO pageReqVO); ``` 那么,在MyBatisXML映射文件中,所有对参数的引用都应该通过`pageReqVO`来访问其属性,比如`pageReqVO.shardSourceIds`。因此,用户当前的写法是正确的,因为`<foreach>`中的`collection="pageReqVO.shardSourceIds"`是正确的引用方式。 另外,需要检查的是,当`shardSourceIds`是一个List时,在生成的SQL语句中,`IN`子句是否正确展开为占位符。例如,如果`shardSourceIds`有三个元素,那么生成的SQL应该是`WHERE temp.dept_id IN (?, ?, ?)`,并且每个占位符对应的参数值正确传递。MyBatis的`<foreach>`标签默认会处理这个过程,使用`item`指定的变量名来替换每个元素。 但是,用户当前的代码中,`<foreach>`的`collection`属性被设置为`pageReqVO.shardSourceIds`,而这里可能存在问题。如果`pageReqVO`是参数对象的名称,那么正确的方式应该是`collection="pageReqVO.shardSourceIds"`。但根据用户提供的代码,他们可能没有在方法参数中使用`@Param`注解,导致MyBatis可能无法正确解析`pageReqVO`作为参数的前缀。 例如,如果方法参数没有使用`@Param`注解,而是直接传递了一个`PageReqVO`对象,那么在XML中应该直接访问其属性,而不需要`pageReqVO.`前缀。例如,`shardSourceIds`而不是`pageReqVO.shardSourceIds`。这种情况下,用户当前的写法就是错误的,因为MyBatis会期望`pageReqVO`作为参数名称存在,但如果没有使用`@Param`,则参数会被默认命名为`param1`,这时候正确的引用方式应该是`param1.shardSourceIds`,或者直接使用属性名`shardSourceIds`,这取决于MyBatis的版本和配置。 这可能导致用户的代码出现错误,例如在运行时无法找到`pageReqVO.shardSourceIds`属性,从而抛出异常。因此,用户是否正确处理了参数的命名是关键问题。 总结可能的错误点: 1. 方法参数未使用`@Param`注解,导致在XML中无法通过`pageReqVO.shardSourceIds`引用属性。 2. `<foreach>`中的`collection`属性是否正确指向了集合参数。 解决方案建议: - 如果方法参数使用了`@Param("pageReqVO")`,则当前写法正确。 - 如果没有使用`@Param`,可能需要将`pageReqVO.shardSourceIds`改为`shardSourceIds`,或者使用`param1.shardSourceIds`(如果参数位置是第一个)。 因此,用户需要检查他们的DAO/Mapper接口方法是否正确地使用了`@Param`注解来命名参数,以确保在XML中能够正确引用。 此外,用户还应该验证生成的SQL是否正确,特别是IN子句是否被正确展开,以及参数是否正确传递。可以通过开启MyBatis的日志功能来查看实际执行的SQL语句,从而确认是否存在问题。 最后,关于SQL片段的写法,用户使用了`<include refid="talentSharedSource"/>`,这需要确保该id对应的SQL片段在同一个XML文件中存在,并且结构正确,否则可能导致SQL拼接错误。 综上,用户当前的写法是否正确,取决于方法参数是否正确地使用了`@Param`注解来命名参数为`pageReqVO`。如果是,则正确;否则需要调整参数引用方式。</think>您的MyBatis SQL片段整体逻辑正确,但需注意以下细节: ### 1. 参数命名问题 - **若方法参数未加`@Param`注解**: MyBatis默认通过`param1`访问第一个参数,此时应改为: ```xml <if test="param1.shardSourceIds != null and param1.shardSourceIds.size() > 0"> <foreach collection="param1.shardSourceIds" ...> ``` 或直接使用属性名(需确保参数对象是唯一入参): ```xml <if test="shardSourceIds != null and shardSourceIds.size() > 0"> <foreach collection="shardSourceIds" ...> ``` - **若方法参数加了`@Param("pageReqVO")`注解**: 当前写法完全正确,无需修改。 ### 2. 集合判空优化 建议将`size > 0`改为`!isEmpty()`更规范: ```xml <if test="pageReqVO.shardSourceIds != null and !pageReqVO.shardSourceIds.isEmpty()"> ``` ### 3. 参数传递验证 通过MyBatis日志确认生成的SQL是否符合预期,例如: ```sql WHERE temp.dept_id IN (?, ?, ?) -- 参数值是否正确绑定 ``` ### 总结 - **正确性前提**:确保方法参数通过`@Param("pageReqVO")`明确命名。 - **改进建议**:优化集合判空逻辑,并通过日志验证参数绑定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Whitemeen太白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值