一、场景还原(主要是业务逻辑有问题)

非管理员的多部门查询出对应部门的列表,分页失效

 public List<SysTest> selectList(String name) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        List<SysTest> SysTestList = new ArrayList<>();
        //管理员全部数据
        if (user.getDeptId() == null) {
            // 获取列表
            SysTestList = sysTestMapper.selectList(name);

        //非管理员对应列表
        } else {
            //多部门处理
            if (user.getDeptId2().contains(",")) {
                String[] deptIds = user.getDeptId2().split(",");
                for (String deptId : deptIds) {
                    List<SysTest> sysTestList2= sysTestMapper.selectList2(name, deptId);
                    for (SysTest sysTest: sysTestList2) {
                        sysTestList .add(sysTest);
                    }
                }
            //单个部门处理
            } else {
                List<SysTestList> sysTestList2 = sysTestMapper.selectList2(name, user.getDeptId2());
                for (SysTest sysTest : sysTestList2 ) {
                    sysTestList.add(sysTest);
                }
            }
        }
     
        return sysTestList;
    }

 二、问题分析

       通过多次调用 Mapper.selectList2(name, deptId) 来获取数据,分页插件无法拦截这些查询,导致分页失效。分页插件只能对原始查询结果进行分页,无法对合并后的结果进行分页。

分页插件的工作原理:

  • MyBatis 分页插件(如 PageHelper)是通过拦截 SQL 查询来实现分页的。

  • 只有在 startPage() 之后执行的第一个查询会被分页插件拦截并分页。

  • 在 else 分支中,我通过循环多次调用 selectList2,这些查询不会被分页插件拦截

 三、解决方案

优化 SQL 查询,统一分页逻辑

  <if test="deptIds != null and deptIds.size() > 0">
        AND sys_sq.dept_id IN
        <foreach collection="deptIds" item="deptId" open="(" separator="," close=")">
            #{deptId}
        </foreach>
    </if>

<select id="selectList" resultType="SysTest">
    SELECT  * FROM sys_test
    LEFT JOIN sys_sq ON sys_test.id = sys_sq.rc_id
    WHERE sys_sq.status = 3

    <if test="name != null and name != ''">
        AND sys_rc.name LIKE CONCAT('%', #{name}, '%')
    </if>

    <if test="deptIds != null and deptIds.size() > 0">
        AND sys_sq.dept_id IN
        <foreach collection="deptIds" item="deptId" open="(" separator="," close=")">
            #{deptId}
        </foreach>
    </if>

</select>

Mapper 接口:String  deptId改成List<String> deptIds

List<SysTest> selectList(@Param("name") String name, @Param("deptIds") List<String> deptIds);

 Service 实现:else重新写

 public List<SysTest> selectList(String name) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        List<SysTest> SysTestList = new ArrayList<>();
        //管理员全部数据
        if (user.getDeptId() == null) {
            // 获取列表
            SysTestList = sysTestMapper.selectList(name);

        //非管理员对应列表
        } else {
           List<String> deptIds = Arrays.asList(user.getDeptId2().split(","));
            return sysTestMapper.selectList(name, deptIds);
        }
     
        return sysTestList;
    }

Controller 保持不变:


@GetMapping("/selectList")
public TableDataInfo selectList(String name) {
    startPage();
    List<SysTest> list = this.selectList(name);
    return getDataTable(list);
}

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐