ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

MyBatis中使用collection一对多分页查询时记录数量不准确的问题

2022-02-21 19:59:33  阅读:301  来源: 互联网

标签:UPPER GROUP 分页 collection USER MyBatis ug ID NAME


假设有如下实体表USER和USER_GROUP,及其映射表USER_MAPPING_USER_GROUP

USER
IDUSER_ACCOUNTUSER_NAME
1zhangsan  张三
USER_GROUP
IDUSER_GROUP_NAME
1管理员组
USER_MAPPING_USER_GROUP
USER_IDUSER_GROUP_ID
11

现在要根据传入的查询参数:USER_ACCONT和USER_GROUP_NAME 对 USER表进行分页查询,在MyBatis中使用resultMap中的collection实现一对多查询时查询返回的记录数量和总数量会出现不符合实际情况的问题,如下的sql代码所示,原因在于主表USER left join映射表USER_MAPPING_USR_GROUP和从表USER_GROUP时,返回的记录中包含主表字段(USER_ACCOUNT等)和从表字段(USER_GROUP_NAME等),自然而然就多于只查询主表返回的记录数量了。

<!--mybatis+oracle-->
<select id="selectUserGroupInfoByCondition" parameterType="string" resultMap="UserGroupMap">  
select uu.*, ug.ID USER_GROUP_ID, ug.USER_GROUP_NAME from (
        select
        u.ID,UPPER(u.USER_NAME) as USER_NAME,UPPER(u.USER_ACCOUNT) as
        USER_ACCOUNT
        from "USER" u
        WHERE 1=1
        <if test="param.userAccount != null and param.userAccount !=''">
            AND UPPER(u.USER_ACCOUNT) LIKE UPPER(CONCAT(CONCAT('%',#{param.userAccount,jdbcType=VARCHAR}),'%'))
        </if>
        ) uu
            left join ${module}."USER_MAPPING_USER_GROUP" umug on uu.ID = umug.USER_ID
             left join ${module}."USER_GROUP" ug on umug.USER_GROUP_ID = ug.ID
        where 1=1
        <if test="param.userGroupName != null and param.userGroupName !=''">
            AND UPPER(ug.USER_GROUP_NAME)  = #{param.userGroupName,jdbcType=VARCHAR}
            and ug.IS_DELETE = 'N'
        </if>
        ORDER BY uu.ID
    </select>


<resultMap type="com.portal.entity.User" id="UserGroupMap">
        <!-- 配置用户主键 -->
        <id column="ID" property="id" jdbcType="DECIMAL"/>
        <!-- 配置普通属性 -->
        <result column="USER_NAME" property="userName" jdbcType="VARCHAR"/>
        <result column="USER_ACCOUNT" property="userAccount"/>
        <collection property="userGroups" ofType="com.xxx.xxx.UserGroup" javaType="list">
            <id column="USER_GROUP_ID" property="id"/>  <!--主键字段,oracle中的 number类型 对应 DECIMAL-->
            <result column="USER_GROUP_NAME" property="userGroupName"/>  <!-- oracle中的 varchar2类型 对应 VARCHAR -->
        </collection>
</resultMap>

如何解决该问题,pagehelper已经提示不支持上面这种情况的查询了。https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/Important.md 

解决该问题的思路很直接,手写分页逻辑就可以了,因为非常简单。

于是上面的sql查询语句就变为下面的。

  <select id="selectUserGroupInfoByCondition" parameterType="string" resultMap="UserGroupMap">
        SELECT pagea.*, ug.USER_GROUP_NAME,ug.ID USER_GROUP_ID FROM
        (SELECT * FROM (select pageb.*, ROWNUM ROW_ID from (
        select distinct uu.ID,uu.USER_NAME,uu.USER_ACCOUNT
        from
        (
            select
        u.ID,UPPER(u.USER_NAME) as USER_NAME,UPPER(u.USER_ACCOUNT) as
        USER_ACCOUNT
        from "USER" u
        WHERE 1=1
        <if test="param.userAccount != null and param.userAccount !=''">
            AND UPPER(u.USER_ACCOUNT) LIKE UPPER(CONCAT(CONCAT('%',#{param.userAccount,jdbcType=VARCHAR}),'%'))
        </if>
        ) uu
            left join "USER_MAPPING_USER_GROUP" umug on uu.ID = umug.USER_ID
             left join "USER_GROUP" ug on umug.USER_GROUP_ID = ug.ID
        where 1=1
        <if test="param.userGroupName != null and param.userGroupName !=''">
            AND UPPER(ug.USER_GROUP_NAME)  = #{param.userGroupName,jdbcType=VARCHAR}
        </if>
        ORDER BY uu.ID )  pageb WHERE ROWNUM &lt; ${param.pageSize} + ${param.currentPage})
        WHERE ROW_ID >= #{param.currentPage,jdbcType=DECIMAL} ) pagea
        left join "USER_MAPPING_USER_GROUP" umug on pagea.ID = umug.USER_ID
        left join "USER_GROUP" ug on umug.USER_GROUP_ID = ug.ID
    </select>

<!--查询总数量-->
<select id="countUserGroupINfoByCondition" parameterType="string" resultType="java.lang.Long">
        select count (distinct uu.ID)
        from
        (
        select
        u.ID,UPPER(u.USER_NAME) as USER_NAME,UPPER(u.USER_ACCOUNT) as
        USER_ACCOUNT
        from "USER" u
        WHERE 1=1 
        <if test="param.userAccount != null and param.userAccount !=''">
            AND UPPER(u.USER_ACCOUNT) LIKE UPPER(CONCAT(CONCAT('%',#{param.userAccount,jdbcType=VARCHAR}),'%'))
        </if>
        ) uu
        left join "USER_MAPPING_USER_GROUP" umug on uu.ID = umug.USER_ID
        left join "USER_GROUP" ug on umug.USER_GROUP_ID = ug.ID
        where 1=1
        <if test="param.userGroupName != null and param.userGroupName !=''">
            AND UPPER(ug.USER_GROUP_NAME)  = #{param.userGroupName,jdbcType=VARCHAR}
        </if>
        ORDER BY uu.ID
    </select>

标签:UPPER,GROUP,分页,collection,USER,MyBatis,ug,ID,NAME
来源: https://blog.csdn.net/lgq2016/article/details/123053831

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有