PageHelper 丢失参数

PageHelper 5.2.0版本

起因

一个很早以前的接口前段突然要使用

调用后发现无法查询到数据

查看日志发现

PageHelper 分页 Count SQL

1
SELECT count(0) FROM (SELECT (round(6367000 * 2 * asin(sqrt(pow(sin(((m.latitude * pi()) / 180 - (/*latitude*/39 * pi()) / 180) / 2), 2) + cos((/*latitude*/39 * pi()) / 180) * cos((m.latitude * pi()) / 180) * pow(sin(((m.longitude * pi()) / 180 - (/*longitude*/39 * pi()) / 180) / 2), 2))))) AS distance FROM sel_mal m WHERE m.status = 1 AND m.mall_id = /*mallId*/39) table_count

分页后进行查询的SQL

1
select (round(6367000 * 2 * asin(sqrt(pow(sin(((m.latitude * pi()) / 180 - (/*latitude*/39 * pi()) / 180) / 2), 2) + cos((/*latitude*/39 * pi()) / 180) * cos((m.latitude * pi()) / 180) * pow(sin(((m.longitude * pi()) / 180 - (/*longitude*/null * pi()) / 180) / 2), 2))))) AS distance from sel_mal m where m.status=1 and m.mall_id = /*mallId*/null ORDER BY distance ASC LIMIT /*Second_PageHelper*/30 

PageHelper 在判断是否需要分页时的 SQL 还有 mallId 这个参数

但是到了 实际分页的 SQL 时 mallId 这个参数就丢失了

原始XML

1
2
3
4
5
6
7
select (round(6367000 * 2 * asin(sqrt(pow(sin(((m.latitude * pi()) / 180 - (#{latitude} * pi()) / 180) / 2), 2) + cos((#{latitude} * pi()) / 180) * cos((m.latitude * pi()) / 180)
* pow(sin(((m.longitude * pi()) / 180 - (#{longitude} * pi()) / 180) / 2), 2))))) AS distance
from sel_mal m
where
m.status=1
and m.mall_id = #{mallId}
ORDER BY distance ASC

请求参数在分页时还存在

分页后却消失了 变成 null 导致查询不到数据

断点调试 PageHelper

根据 PageInterceptor 源码

Count 时 没有修改 parameter 变量

因为 入参没有变动 所以 PageHelper 使用了原始的 parameter 进行查询 查询结果就没有任何问题

而 PageHelper 进行分页时

增加了 /Second_PageHelper/30 参数

我原方法 是

SelMalPo selectByMall(Long mallId);

单个参数的方法

PageHelper 对请求参数进行修改

变更为 paramMap HashMap 用于传递自身所需要的 limit size

在 AbstractHelperDialect 114行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 //下面这段方法,主要解决一个常见类型的参数时的问题
if (boundSql.getParameterMappings() != null && boundSql.getParameterMappings().size() > 0) {
for (ParameterMapping parameterMapping : boundSql.getParameterMappings()) {
String name = parameterMapping.getProperty();
if (!name.equals(PAGEPARAMETER_FIRST)
&& !name.equals(PAGEPARAMETER_SECOND)
&& paramMap.get(name) == null) {
if (hasTypeHandler
|| parameterMapping.getJavaType().equals(parameterObject.getClass())) {
paramMap.put(name, parameterObject);
break;
}
}
}

注入参数时

由于我的SQL比较特殊

里面有3个 #{latitude} 1个 #{mallId}

PageHelper 根据 参数类型 Long 匹配后 将 latitude = 39 而 mallId 这个变量没有赋值

导致了以上问题

总结

这个问题是由于特殊情况产生的

SQL 中有多个需要传递的参数

但方法个只声明了一个参数

导致 PageHelper 判断错误