Mybatis-PageHelper
Mybatis-PageHelper copied to clipboard
不开启分页时,sql中的order by会被重写,导致sql语法查询错误
pagehelper版本:5.1.11 mysql版本:8.0.12
问题描述:在springboot项目中,配置了pagehelper插件,在实现查询中,不开启分页直接使用mapper查询,查询参数中包含了orderBy字段,执行查询时,pagehelper会重写sql中的order by字段,导致查询错误。
问题分析:
/**
* 排序枚举
*/
@Getter
@AllArgsConstructor
public enum OrderBy {
CREATE_TIME_DESC("create_time", "desc");
private final String field;
private final String order;
}
/**
* 查询条件
*/
@Data
@AllArgsConstructor
public enum QueryCond {
private OrderBy orderBy;
}
// Mapper 接口
public List<Entity> query(QueryCond cond);
sql模版:select * from t_table order by #{orderBy.field} #{orderBy.order}
// 调用,不开启分页
mapper.query(cond);
mybatis解析后的boundsql:select * from t_table order by create_time desc;
pagehelper拦截后的sql:select * from t_table order by CREATE_TIME_DESC;
问题原因:
如果不开启分页,并且supportMethodsArguments为true的情况下,由于不开启分页所以在线程中Page对象为null,com.github.pagehelper.page.PageParams#getPage会调用com.github.pagehelper.util.PageObjectUtil#getPageFromObject构建一个Page对象

在getPageFromObject方法中,从查询参数中获取orderBy字段,如果存在,设置到Page对象的orderBy字段中,设置时直接通过调用toString方法设置,所以这里得到的值是CREATE_TIME_DESC

在com.github.pagehelper.dialect.AbstractHelperDialect#getPageSql()方法中,如果Page对象orderBy值不为空,就执行sql转换,所以导致sql中的order by create_time desc被转换为order by CREATE_TIME_DESC,导致查询错误

把默认的orderBy参数名通过params改写即可。