MyBatis-Plus 在使用Page进行分页查询的时候,会生成查询数量的sql,但是在生成sql的时候会对原sql进行优化,
JsqlParserCountOptimize
1.添加包含groupBy 不去除orderBy
if (null == groupBy && CollectionUtils.isNotEmpty(orderBy)) {
plainSelect.setOrderByElements(null);
sqlInfo.setOrderBy(false);
}
2.selectItems contains #{} ${}, which will be translated to ?, and it may be in a function: power(#{myInt},2)
for (SelectItem item : plainSelect.getSelectItems()) {
if (item.toString().contains(StringPool.QUESTION_MARK)) {
return sqlInfo.setSql(SqlParserUtils.getOriginalCountSql(selectStatement.toString()));
}
}
3.包含 distinct、groupBy不优化
if (distinct != null || null != groupBy) {
return sqlInfo.setSql(SqlParserUtils.getOriginalCountSql(selectStatement.toString()));
}
4.包含 join 连表,进行判断是否移除 join 连表
if (optimizeJoin && CollectionUtils.isNotEmpty(joins)) {
boolean canRemoveJoin = true;
String whereS = Optional.ofNullable(plainSelect.getWhere()).map(Expression::toString).orElse(StringPool.EMPTY);
for (Join join : joins) {
if (!join.isLeft()) {
canRemoveJoin = false;
break;
}
Table table = (Table) join.getRightItem();
String str = Optional.ofNullable(table.getAlias()).map(Alias::getName).orElse(table.getName()) + StringPool.DOT;
String onExpressionS = join.getOnExpression().toString();
/* 如果 join 里包含 ?(代表有入参) 或者 where 条件里包含使用 join 的表的字段作条件,就不移除 join */
if (onExpressionS.contains(StringPool.QUESTION_MARK) || whereS.contains(str)) {
canRemoveJoin = false;
break;
}
}
if (canRemoveJoin) {
plainSelect.setJoins(null);
}
}
5.优化 SQL
plainSelect.setSelectItems(COUNT_SELECT_ITEM);
COUNT_SELECT_ITEM 这里就是count(1)
会出现的问题
就是对于上边的第4点,如果 join 里不包含 ?(代表有入参) 或者 where 条件里不包含使用 join 的表的字段作条件 就是把 join表给优化掉,如果主表和关联表是一对多的关系,那么最后查询出来的count是主表的总数据,就不对了
解决方法
将sql 的count优化关掉
page.setOptimizeCountSql(false);