前言
在项目中,使用mybatis做一对多关联,出现数据条数不匹配的情况,比如要查询10条,由于一对多的关系导致最终得到的数据条数变少。利用子查询解决。
解决代码
直接上解决后的代码。
SELECT
t.ID,
t.USER_ID,
t.NAME,
t.CONTENT,
t.DESCRIPTION,
t.STATUS,
t.FAVO_COUNT,
t.USE_COUNT,
t.CREATE_TIME,
tag.ID tagId,
tag.NAME tagName,
tag.TYPE tagType
FROM
t_template t
INNER JOIN t_template_tag tt ON t.ID = tt.TEMPLATE_ID
INNER JOIN t_tag tag ON tt.TAG_ID = tag.ID
WHERE
t.ID IN (
SELECT
temp.ID
FROM
(
SELECT DISTINCT
t.ID
FROM
t_template t
INNER JOIN t_template_tag tt ON t.ID = tt.TEMPLATE_ID
INNER JOIN t_tag tag ON tt.TAG_ID = tag.ID
LIMIT 0, 10
) temp
)
AND t.STATUS = 1
AND t.IS_ACTIVE = 0
AND tag.IS_ACTIVE = 0
ORDER BY
t.USE_COUNT DESC
可以看到,分页的是 LIMIT 0,10
,很明显是应该返回10条数据,而现是在是返回了15条数据,而且有几个是重复的,这个没问题,由于是一个一对多关系,在mybatis中使用集合映射即可。
mapper.xml
<!--查询首页模版列表响应Map对象-->
<resultMap id="ResultRespMap" type="com.codegen.dao.resq.TemplateListResp">
<id column="ID" property="id" jdbcType="INTEGER" />
<result column="NAME" property="name" jdbcType="VARCHAR" />
<result column="USER_ID" property="userId" jdbcType="INTEGER" />
<result column="CONTENT" property="content" jdbcType="VARCHAR" />
<result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />
<result column="STATUS" property="status" jdbcType="TINYINT" />
<result column="FAVO_COUNT" property="favoCount" jdbcType="INTEGER" />
<result column="USE_COUNT" property="useCount" jdbcType="INTEGER" />
<result column="CREATE_TIME" property="createTime" jdbcType="TIMESTAMP" />
<!--一对多的关系 用collection-->
<!-- property: 指的是集合属性的值, ofType:指的是集合中元素的类型 -->
<collection property="tags" ofType="com.codegen.dao.resq.TagResp">
<!--column是列名 property是属性名 jdbcType是类型-->
<id column="tagId" property="tagId" jdbcType="INTEGER"/>
<result column="tagName" property="tagName" jdbcType="VARCHAR"/>
<result column="tagType" property="tagType" jdbcType="TINYINT" />
</collection>
</resultMap>
<!-- 动态搜索条件 -->
<sql id="Search_By_Selective_Condition">
<where>
AND t.STATUS = #{status, jdbcType=TINYINT}
AND t.IS_ACTIVE = #{isActive, jdbcType=TINYINT}
<if test="userId != null">
AND t.USER_ID = #{userId, jdbcType=VARCHAR}
</if>
<if test="name != null">
AND t.NAME LIKE CONCAT('%',#{name, jdbcType=VARCHAR},'%')
</if>
<if test="description != null">
AND t.DESCRIPTION LIKE CONCAT('%',#{description, jdbcType=VARCHAR},'%')
</if>
</where>
</sql>
<!--搜索首页模版列表-->
<select id="search4HomePage" resultMap="ResultRespMap" parameterType="com.codegen.dao.req.TemplateReq">
SELECT
<include refid="Resp_Column_List" />
FROM
t_template t
INNER JOIN t_template_tag tt ON t.ID = tt.TEMPLATE_ID
INNER JOIN t_tag tag ON tt.TAG_ID = tag.ID
<include refid="Search_By_Selective_Condition" />
AND t.ID IN (
SELECT
temp.ID
FROM
(
SELECT DISTINCT
t.ID
FROM
t_template t
INNER JOIN t_template_tag tt ON t.ID = tt.TEMPLATE_ID
INNER JOIN t_tag tag ON tt.TAG_ID = tag.ID
${pageSql}
) temp
)
AND tag.IS_ACTIVE = #{isActive, jdbcType=TINYINT}
ORDER BY
t.USE_COUNT DESC
</select>
最后接口返回就是10条数据。