查询sql如下:
QueryWrapper wrapper = QueryWrapper.create()
.select(TEACHER_STATISTICS.ALL_COLUMNS,TEACHER.AGE)
.from(TEACHER_STATISTICS)
.leftJoin(TEACHER)
.on(TEACHER_STATISTICS.TEACHER_ID.eq(TEACHER.ID));
使用pageAs方法并禁用page优化
page.setOptimizeCountQuery(false);
继承CommonsDialectImpl
并 Override prepareAuth(QueryWrapper queryWrapper, OperateType operateType)方法,打印CPI如下信息
public class PermissionDialect extends CommonsDialectImpl {
@Override
public void prepareAuth(QueryWrapper queryWrapper, OperateType operateType) {
List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper);
List<QueryTable> joinTables = CPI.getJoinTables(queryWrapper);
System.out.println("queryTables ==" + queryTables);
System.out.println("joinTables ==" + joinTables);
System.out.println("isJoin ==" + CPI.getJoins(queryWrapper));
}
}
实际输出:
queryTables ==[QueryTable{schema='', name='teacher_statistics', alias='null'}]
joinTables ==[QueryTable{schema='', name='teacher', alias='null'}]
isJoin ==[com.mybatisflex.core.query.Join@1b9b21c]
queryTables ==[SELECT `teacher_statistics`.*, `teacher`.`age` FROM `teacher_statistics` LEFT JOIN `teacher` ON `teacher_statistics`.`teacher_id` = `teacher`.`id`]
joinTables ==null
isJoin ==null
2024-06-21 17:17:50.725 INFO 34752 --- [admin-service] [omcat-handler-0] com.sz.logger.PrintSQL : SELECT COUNT(*) AS `total` FROM (SELECT `teacher_statistics`.*, `teacher`.`age` FROM `teacher_statistics` LEFT JOIN `teacher` ON `teacher_statistics`.`teacher_id` = `teacher`.`id`) AS `t` ---- 1ms, row:1
queryTables ==[QueryTable{schema='', name='teacher_statistics', alias='null'}]
joinTables ==[QueryTable{schema='', name='teacher', alias='null'}]
isJoin ==[com.mybatisflex.core.query.Join@1b9b21c]
2024-06-21 17:17:50.734 INFO 34752 --- [admin-service] [omcat-handler-0] com.sz.logger.PrintSQL : SELECT `teacher_statistics`.*, `teacher`.`age` FROM `teacher_statistics` LEFT JOIN `teacher` ON `teacher_statistics`.`teacher_id` = `teacher`.`id` LIMIT 0, 10 ---- 4ms, row:10
根据日志可以看到,在page分页时 cpi相关信息被打印了3次。且一次的信息为
queryTables ==[SELECT `teacher_statistics`.*, `teacher`.`age` FROM `teacher_statistics` LEFT JOIN `teacher` ON `teacher_statistics`.`teacher_id` = `teacher`.`id`]
joinTables ==null
isJoin ==null
其他信息:
禁用page优化的原因:
实际业务为数据权限处理。
针对于非单表场景的动态querywrapper追加。
在启用page优化,left join 场景 优化后的sql 会丢失联查表。通常在常规分页场景这种优化可以满足业务需求。
但比如sql:
# 原始sql
SELECT `teacher_statistics`.*, `teacher`.`age` FROM `teacher_statistics` LEFT JOIN `teacher` ON `teacher_statistics`.`teacher_id` = `teacher`.`id`
# 追加数据权限 (在方言 CommonsDialectImpl中)
+ “and `teacher`.area_id = xxx ”
此种场景因为优化后的sql变成了
SELECT COUNT(*) AS `total` FROM `teacher_statistics`
无法直接执行追加 “and teacher
.area_id = xxx ” 操作。 因此禁用了count优化。
prepareAuth()方法应该只执行两次!
CPI.getQueryTables的输出信息应复合QueryTable结构而非字符串
正确:
queryTables ==[QueryTable{schema='', name='teacher_statistics', alias='null'}]
错误:
ueryTables ==[SELECT teacher_statistics
.*, teacher
.age
FROM teacher_statistics
LEFT JOIN teacher
ON teacher_statistics
.teacher_id
= teacher
.id
]
从日志中不难发现,count时 prepareAuth()
方法执行了三次!! 且一次获取信息为
queryTables ==[SELECT `teacher_statistics`.*, `teacher`.`age` FROM `teacher_statistics` LEFT JOIN `teacher` ON `teacher_statistics`.`teacher_id` = `teacher`.`id`]
数字2 的输出是错误的,它不应该存在。且输出信息与方法标书不符。
v1.9.3