项目场景:
自定义sql,使用mybatis-plus分页出现Parameter index out of range的问题
mybatis-plus-boot-starter版本为3.4.1
pagehelper版本为5.3.2
问题描述
1.IPage分页时突然就出现了如下报错,于是就仔仔细细检查了sql也没发现问题。
在好奇心的驱使下,同样的sql用pagehelper并没有报错
2.sql中若存在left join连表的自定义分页查询可能存在分页count精确度的问题
sql报错内容
SQL片段
SELECT
t1.time,
t1.user_id as userId,
t1.totalCount,
t2.totalCount AS timeCount
FROM
(
SELECT
first_time,
DATE( first_time ) AS time,
user_id,
count( `restrict` ) AS totalCount
FROM
restrict_control_info
WHERE
deleted = 0
AND xxxxx = ?
GROUP BY
time,
user_id
ORDER BY
id DESC
) t1
LEFT JOIN (
SELECT
first_time,
DATE( first_time ) AS time,
user_id,
count( `restrict` ) AS totalCount
FROM
restrict_control_info
WHERE
deleted = 0
AND `xxxxx` = 1
AND xxxxx = ?
GROUP BY
time,
user_id
ORDER BY
id DESC
) t2 ON t1.user_id = t2.user_id
AND t1.time = t2.time
以上sql只是作为参考
原因分析:
随着好奇的心,一路debug开心的走进了源码
具体debug的过程就不多说了,干它
到这里sql的部分就已经ok,那到什么地方会出现参数索引越界的问题?(Parameter index out of range),接着往下走走走
这里会循环设置参数
整个过程就就结束了
重新梳理一遍,在优化sql部分去掉了join连接部分表,优化后的sql中的参数只有一个(其实就是xxx=?),但是parameterMappings参数有两个(其实就是传到xml的sql入参)
解决方案:
方式一
/**
* 可以optimizeCountSql参数改为false,缺省值为true
* optimizeCountSql参数的含义为自动优化count sql
*/
Page<Object> page = new Page<>(1, 10)
page.setOptimizeCountSql(false)
具体的代码片段com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor#autoCountSql中感兴趣的朋友可以看看
方式二
如果不想修改sql,也可以使用pagehelper分页,但是个人不是很建议因为pagehelper和mybatis-plus-boot-starter如果不注意的话会存在版本兼容性的问题,要是项目中pagehelper和mp同时存在,并且没有问题,这种方式也无妨。
方式三
修改本身sql
1.不太建议从#{}改为${}
2.在代码判断中只用使用left join才会优化
3.sql中有使用left join右边的表作为where条件,不会优化count
4.order by带参数、group by、distinct都不会优化count
以上方式可以根据自身情况选择
到这里就结束啦,祝大家生活愉快!