mybatisplus+PageHelper⼀对多查询分页问题
项⽬中使⽤PageHelper进⾏分页查询的时候,发现分页有问题:每页显⽰的数量与传⼊的limit的参数不⼀致。
细细查看之后,发现是由于查询SQL是⼀对多查询,才会出现这样的问题。在⽹上查了⼀些解决⽅案后,最终解决了,下⾯是整个查问题、解决问题的记录。
背景介绍
已知⽤户表User,⾓⾊表Role,⽤户⾓⾊关联表user_role。其中,User和user_role表是⼀对多的关系。要求查询⽤户信息并进⾏分页,其中⽤户信息中需包含该⽤户的所有⾓⾊信息。
问题查
问题页⾯如下图:
1)每⼀页10条/页,第⼀页应该显⽰10条数据,但是表格中只有6条;
2)总条数24,也⽐User表在数据库中的条数(14条)多。
SQL⽂件是这样的:
<resultMap id="userMap" type="ity.User">
<id column="id" property="id"/>
<result column="username" property="username"/>
...
<collection property="roles" ofType="ity.Role">
<id column="role_id" property="id"/>
<result column="role_name" property="roleName"/>
</collection>
</resultMap>
<select id="listByPage" resultMap="userMap" parameterType="xxx.ReqParam">
select a.*, b.role_id, c.role_name
from user a
join user_role b on (a.id = b.user_id)
join role c on (b.role_id = c.id)
<trim prefix="WHERE" prefixOverrides="AND|OR">
<if test="searchKey != null and searchKey != '' and searchValue != null and searchValue != ''">
AND a.${searchKey} like concat('%',#{searchValue},'%')
</if>
</trim>
order ate_date
</select>
查看后台⽇志后发现,PageHelper进⾏分页时是先执⾏⼀个查询count的SQL,得出总条数,后⼜执⾏具体的SQL进⾏信息查询。
<!--这个是查询count的SQL-->
SELECT COUNT(0)
FROM user a
JOIN user_role b ON(a.id = b.user_id)
JOIN role c le_id = c.id)
把这条查询count的SQL拿到数据库执⾏的结果,显⽰count是24:
<!--这个是查询具体信息的SQL-->
SELECT a.*, b.role_id, c.role_name
FROM user a
JOIN user_role b ON(a.id = b.user_id)
JOIN role c le_id = c.id)
ORDER ate_date LIMIT10
把这条查询具体信息的SQL拿到数据库执⾏,查出来是10条记录:
这样⼀看,原因就显⽽易见了:
因为User和user_role表是⼀对多的关系,所以在关联查询时,虽然是查出来了10条记录,但是这10条记录中,user有重复的(因为⼀个user有多个⾓⾊)。
⽽这些记录在封装成User对象返回前端时,会按User进⾏逐个封装,这样就会出现数量减少的情况。
问题解决
<resultMap id="userMap" type="ity.User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="nick_name" property="nickName"/>
<result column="real_name" property="realName"/>
<result column="avatar" property="avatar"/>
<result column="sex" property="sex"/>
<result column="phone" property="phone"/>
<result column="email" property="email"/>
<result column="state" property="state"/>
<result column="create_date" property="createDate"/>
<result column="update_date" property="updateDate"/>
<result column="company_id" property="companyId"/>
<result column="company_name" property="companyName"/>
<result column="office_id" property="officeId"/>
<result column="office_name" property="officeName"/>
<collection property="roles" ofType="ity.Role"
javaType="java.util.List" select="getRoleInfo" column="id">
</collection>
</resultMap>
<resultMap id="roles" type="ity.Role">
<id column="role_id" property="id"/>
<result column="role_name" property="roleName"/>
</resultMap>
<select id="getRoleInfo" parameterType="java.lang.String" resultMap="roles">
le_id, c.role_name
from user_role b
join role c on (b.role_id = c.id)
where b.user_id = #{id}
</select>
<select id="listByPage" resultMap="userMap" parameterType="xxx.ReqParam">
select a.*
from user a
<trim prefix="WHERE" prefixOverrides="AND|OR">
<if test="searchKey != null and searchKey != '' and searchValue != null and searchValue != ''">
AND a.${searchKey} like concat('%',#{searchValue},'%')
分页查询插件</if>
</trim>
order ate_date
</select>
将主要的查询语句剥离出来,需要关联表查询的信息,通过配置相应的collection,并设置select指向相关的查询sql:
1:先将User主表查询SQL1拆出来
2:在这个SQL1的resultMap=“userMap” 中配置collection ,指向查询这个⽤户对应的⾓⾊的SQL2(select=“getRoleInfo”)3:在查询这个⽤户对应的⾓⾊的SQL2中,通过resultMap="roles"进⾏查询结果映射
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论