解决RuoYiPro的mybatisPuls中由于数据权限问题自动在sql后拼接 “and null” 的问题
问题复现:
问题描述:
由于开启了多租户功能,所以再查询部门表的时候会自动拼接上Tenant_id,用于隔离不同租户单位的数据,但是又多拼接了 “and null”
问题排查:
首先debug,定位到拼接sql的地方,既mybatisPlus的sql拦截器(InnerInterceptor)
由DataPermissionDatabaseInterceptor类实现了mybatisPlus的拦截器,会调用到对应的sql类型的实现方法,比如select或update等等,然后构建MPBoundSql类执行sql操作,在执行sql操作之前,对sql进行拦截,并拼接需要的sql,即通过调用parseSingle()函数进行解析sql
再判断出是select类型时,调用DataPermissionDatabaseInterceptor类重写的processSelect()方法,而不是当前的this方法(当前方法直接抛出异常,就是如果不重写就抛异常)
诡异的地方出来了,在处理mainTable的时候调用了一个builderExpression()的函数,看名称应该是构建条件参数的,点进去看,破案了
这里会判断一下查询的表是否有数据权限控制,如果有,还要查询当前用户的数据权限是否符合
依次点进去看会看到构建参数的过程
出问题的关键就在这里,由于没有获取到数据权限,这里会返回一个null的数组,导致后续sql拼接的时候出现 “and null”的情况,成功破案
最终的解决方案:
原本的逻辑是没问题的,问题的根源就在于没有查到数据权限的数据,之所以没有查到,是因为数据不在这里维护,得改从其他地方查
PS:
这个问题排查了很久,但是如果把执行的sql的日志打出来会更容易排查,我这次也是忽略了日志,导致做了很多多余的排查,
就是这个日志,打印的日志太长了导致没看完全,以为不重要以至于忽略了,
这个也有解决方法:
加一个换行符合解决。
以上就是这次非Admin账号的数据库执行命令拼接了and null 问题的解决思路和过程。