219 Star 2.4K Fork 479

MyBatis-Flex / MyBatis-Flex

 / 详情

[Bug]: CPI 方法获取参数不一致问题

待办的
创建于  
2024-06-21 17:39

这个 Bug 是否已经存在:

如何复现:

  1. 查询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));
    
  2. 使用pageAs方法并禁用page优化

    page.setOptimizeCountQuery(false);
    
  3. 继承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


其他信息:

  • jdk:21
  • springboot:3.2.5

禁用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

评论 (0)

INS6 创建了任务
INS6 添加了
 
bug
标签
展开全部操作日志

登录 后才可以发表评论

状态
负责人
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
参与者(1)
5315044 feiyuchuixue 1718845171
1
https://gitee.com/mybatis-flex/mybatis-flex.git
git@gitee.com:mybatis-flex/mybatis-flex.git
mybatis-flex
mybatis-flex
MyBatis-Flex

搜索帮助

344bd9b3 5694891 D2dac590 5694891