MyBatis自定义插件,增加查询sql的查询条件,普通账户的sql增加条件,导致超管的sql也增加了查询条件(超管不增加)。代码如下:
自定义插件:
@Intercepts({@Signature(
method = "query",
type = Executor.class,
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
)})
public class InstancePermissionPlugin implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
logger.debug("args {}, {}", args.length, args);
MappedStatement ms = (MappedStatement)args[0];
Object params = args[1];
BaseRequestModel baseEntity = null;
if (params instanceof Map) {
Iterator var6 = ((Map)params).values().iterator();
while(var6.hasNext()) {
Object obj = var6.next();
if (obj instanceof BaseRequestModel) {
baseEntity = (BaseRequestModel)obj;
break;
}
}
} else if (params instanceof BaseRequestModel) {
baseEntity = (BaseRequestModel)params;
}
if (baseEntity == null) {
return invocation.proceed();
} else if ((!StringUtils.isEmpty(baseEntity.getPermissionUser()) || !Collections3.isEmpty(baseEntity.getDeptList())) && baseEntity.getIsIntercept()) {
PermissionDataKey annotation = (PermissionDataKey)baseEntity.getClass().getAnnotation(PermissionDataKey.class);
if (annotation == null) {
return invocation.proceed();
} else {
//普通用户此处修改sql
......
//普通用户吸怪了args[0],即MappedStatement
args[0] = this.updateMs(ms, params, plainSelect.toString());
}
} else {
//超管没有修改,直接过了
return invocation.proceed();
}
}
}
分页插件配置:
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 4.0.0以后版本可以不设置该参数
<property name="dialect" value="mysql" />-->
<!-- 该参数默认为false -->
<!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
<!-- 和startPage中的pageNum效果一样 -->
<property name="offsetAsPageNum" value="true" />
<!-- 该参数默认为false -->
<!-- 设置为true时,使用RowBounds分页会进行count查询 -->
<property name="rowBoundsWithCount" value="true" />
<!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
<!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型) -->
<property name="pageSizeZero" value="true" />
<!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
<!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
<!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
<property name="reasonable" value="false" />
<!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
<!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
<!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值 -->
<!-- 不理解该含义的前提下,不要随便复制该配置 -->
<property name="params"
value="pageNum=pageHelperStart;pageSize=pageHelperRows;" />
<!-- 支持通过Mapper接口参数来传递分页参数 -->
<property name="supportMethodsArguments" value="false" />
<!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
<property name="returnPageInfo" value="none" />
</plugin>
<plugin interceptor="com.minstone.common.plugin.InstancePermissionPlugin"></plugin>
</plugins>
分页插件改变MappedStatement的SqlSource属性为PageSqlSource类型,PageSqlSource即分页sql,并缓存到Map<String, MappedStatement> msCountMap中,
MappedStatement已经被分页插件修改为SqlPageSource了。普通用户修改了sql,由于普通用户每次的MappedStatement都是新建的,因此SqlSource不是PageSourceSql类型,所以每次都会放一个新的到msCountMap中,由于ms.getId和超管的一样,所以会把超管的MappedStatement覆盖,超管的不是新建的MappedStatement,所以SqlSource字段的类型是PageSqlSource,所以是直接从msCountMap获取MappedStatemen,导致sql是普通用户的SQL,导致查询出来的数据是错误的。
解决办法是在自定义插件中,超管的也新建一个MappedStatement,这样SqlSource就不是PageSqlSource,每次的都是新的,就不会用到普通用户的SQL。