记录一个关于PageHelper的坑

记录一个关于PageHelper的坑

下面是部分代码,我在方法中并没有使用PageHelper.startPage()方法开启分页,
但还是进行了分页查询,于是开始找原因,一开始怀疑是其他方法调用了PageHelper.startPage(),
并且PageHelper.startPage()方法的作用域是类,但是PageHelper.startPage()方法的作用域是跟
线程绑定的,并且只对调用startPage()方法之后紧随其后的第一个SQL查询有效,那为什么我并没有
使用PageHelper.startPage()方法开启分页还是进行了分页呢,找不到原因于是开始尝试在此方法内禁掉分页查询
@RequestMapping(value = "/query_ot_list_count")
    public ResultResponse<PageResp<OtCountVo>> queryOtListCount(@RequestBody OtCountDto otCountDto) {
        LOG.info("查加班统计列表:{}", JSON.toJSONString(otCountDto));
        ResultResponse<PageResp<OtCountVo>> result=new ResultResponse<PageResp<OtCountVo>>();
        /**判断 学校id**/
        if (CoreUtils.isNull(otCountDto)||CoreUtils.isNull(otCountDto.getSchoolId())) {
            result.setRescode(RespConsts.PARAM_ERROR);
            result.setResmsg("学校id不可以为空");
            return result;
        }
        PageResp<OtCountVo> pageResp = otBusiness.queryOtListCount(otCountDto);
        try {
            /**封装参数**/
            result.setData(pageResp);
            result.setRescode(RespConsts.SUCCESS_RET);
            result.setResmsg("SUCCESS");
        }catch (Exception e){
            LOG.error(e.getMessage(), e);
            result.setResmsg("查询加班统计列表失败");
            result.setRescode(RespConsts.SERVICE_ERROR);
        }
        return result;
    }
public PageResp<OtCountVo> queryOtListCount(OtCountDto otCountDto) {
//        清除之前的分页设置
//        PageHelper.clearPage();
        List<OtCountVo> otCountVos = otInfoDao.selectOtsByOtCountDtos(otCountDto);
}
public class OtCountDto implements Serializable {

    private Integer applyUserId;
    private Integer applyDeptId;
    private String applyUserName;
    private String applyDeptName;
    private Integer schoolId;
    private Float otTimeCount;
    private Date startTime;
    private Date endTime;
    private List<Integer> applyUserIds;
    private Integer sort = 1;
    private Integer pageSize;     //怀疑对象
    private Integer pageNum;     //怀疑对象
    private Integer searchAll;
    private Integer setting = 1;

方法一

 		  清除之前的分页设置
        PageHelper.clearPage();
//使用了此方法没用,还是会进行分页

方法二

page.setSize(-1L);
//此方法生效了,但是出现了一个奇怪的bug,sum函数聚合查询的数据没了
//注意看OtCountDto实体类中的两个属性
    private Integer pageSize;     //怀疑对象
    private Integer pageNum;     //怀疑对象
    我怀疑是这两个参数的问题,于是将
    private Integer pageSize  改成
    private Integer pageSSS
//于是成了,不进行分页查询了,我也不知道为什么
//开始说解决方法,上面更改参数名解决了问题,但是为了命名规范,舍弃了上面的方法
//使用BeanUtil转成map集合
Map<String, Object> stringObjectMap = BeanUtil.beanToMap(otCountDto);
对应的mapper和xml文件如下
public List<OtCountVo> selectOtsByOtCountDtos(@Param("params") Map<String,Object> params);
<select id="selectOtsByOtCountDtos" resultMap="OAOTResultMap" parameterType="java.util.Map">
        SELECT apply_user_id,apply_user_name,
               GROUP_CONCAT(DISTINCT apply_dept_name ORDER BY apply_dept_name ASC SEPARATOR '、') AS apply_dept_name,
                sum(ot_time_count) as sumOtTimeCount
        FROM t_oa_ot
        <trim prefix="WHERE" prefixOverrides="AND">
            <if test="params.startTime != null"> AND create_time >= #{params.startTime}</if>
            <if test="params.endTime != null "> AND #{params.endTime} >= create_time </if>
        <if test="params.applyUserIds != null and params.applyUserIds.size() > 0">
            AND apply_user_id IN
            <foreach item="params.applyUserId" collection="params.applyUserIds" open="(" separator="," close=")">
                #{params.applyUserId}
            </foreach>
        </if>
        </trim>
        GROUP BY apply_user_id
</select>
开始继续深究分页问题,查了很多资料,说是可能线程污染,在其他方法调用了startPage(),
但是发生异常没有调用对应的sql,当前线程ThreadLocal设置了分页参数但是没有被消费,
就会导致线程污染,于是我开始查看日志,确定没有此问题,但还是进行了分页,不懂,求大佬解答
//记录一个安全使用PageHelper的方法
List<Country> list;
if(param1 != null){
    PageHelper.startPage(1, 10);
    try{
        list = countryMapper.selectAll();
    } finally {
        PageHelper.clearPage();
    }
} else {
    list = new ArrayList<Country>();
}

<think>好的,我需要帮助用户了解PageHelper分页查询中total属性的使用方法和常见问题。首先,我应该回顾一下用户提供的引用内容,看看里面有没有关于total的具体信息。引用[3]提到Page分页信息包含总数据条数,也就是total,这应该和用户的问题相关。 接下来,我需要整理total属性的使用方法。根据引用[1]和[2],PageHelper通过PageInfo对象包装查询结果,而PageInfo中就包含total属性。用户可能需要知道如何获取这个值,例如通过PageInfo的getTotal()方法。此外,引用[3]指出分页参数存储在ThreadLocal中,这可能会影响total的正确性,尤其是在多线程环境下,需要注意线程隔离的问题。 然后,常见问题部分需要考虑用户在实际使用中可能遇到的。比如,total为0的情况,可能是PageHelper.startPage()方法的位置对,或者在分页语句前有未正确拦截的查询。另外,当手动设置total时,如果未关闭分页,可能会导致后续查询错误,这也是需要注意的点。此外,分页插件对数据库的支持情况(引用[1]提到的12种数据库)可能影响total的准确性,需要确保使用的数据库被支持。 最后,生成的相关问题需要围绕PageHelper的其他功能,比如分页优化、多表联查的分页处理,以及物理分页和逻辑分页的区别,这些都能帮助用户更全面地理解PageHelper的使用。</think>### PageHelper分页查询中total属性的使用与常见问题 #### 一、total属性的作用 `total`属性表示**满足条件的数据总量**(忽略分页限制的总记录数),在分页查询中常用于计算总页数或展示数据规模。例如: $$总页数 = \lceil \frac{total}{pageSize} \rceil$$ #### 二、使用方法 1. **自动获取total** ```java PageHelper.startPage(1, 10); //开启分页(页码=1,每页数量=10) List<User> userList = userMapper.selectAll(); //实际SQL会被自动改写为"LIMIT 0,10" PageInfo<User> pageInfo = new PageInfo<>(userList); long total = pageInfo.getTotal(); //通过PageInfo获取total[^2] ``` 2. **手动设置total** ```java Page<User> page = PageHelper.startPage(1, 10).doSelectPage(() -> userMapper.selectAll()); page.setTotal(1000); //手动覆盖自动计算的total值 ``` #### 三、常见问题及解决方案 1. **total=0的情况** - 原因:`PageHelper.startPage()`未正确生效 - 检查点: - 确保`startPage()`在查询方法**之前调用**[^3] - 确认SQL语句被PageHelper拦截(查看控制台输出SQL是否包含分页语句) - 避免在分页查询前出现未被拦截的查询操作 2. **多线程环境异常** - 现象:分页参数错乱 - 原因:PageHelper通过`ThreadLocal`存储分页参数 - 解决:异步查询时需手动清理线程变量 ```java PageHelper.startPage(1, 10); try { userMapper.selectAll(); } finally { PageHelper.clearPage(); //强制清除ThreadLocal } ``` 3. **total值准确** - 场景:复杂SQL(含UNION/子查询) - 解决:使用`PageHelper.count()`手动执行count查询 ```java long total = PageHelper.count(() -> userMapper.selectComplexQuery()); ``` #### 四、性能优化建议 1. 对count查询进行优化(如添加索引) 2. 使用`PageHelper.setCountSignal(true)`强制执行count查询验证准确性[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值