1. 在使用MybatisPlusInterceptor想对数据权限做限制,但是发现使用寻常的配置,在执行sql后也不会被拦截 代码如下:
@Configuration public class MybatisPlusConfig { public MybatisPlusInterceptor setMybatisPlusInterceptor(){ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new DataPermissionInterceptor(new MyDataPermissionHandler())); return interceptor; } }
执行sql语句后拦截器没有反应
@Slf4j public class MyDataPermissionHandler implements DataPermissionHandler {@Override@SneakyThrowspublic Expression getSqlSegment(Expression where, String mappedStatementId) {// 超级管理员不受数据权限控制Class<?> clazz = Class.forName(mappedStatementId.substring(0, mappedStatementId.lastIndexOf(StringPool.DOT)));String methodName = mappedStatementId.substring(mappedStatementId.lastIndexOf(StringPool.DOT) + 1);Method[] methods = clazz.getDeclaredMethods();for (Method method : methods) {DataPermission annotation = method.getAnnotation(DataPermission.class);if (ObjectUtils.isNotEmpty(annotation)&& (method.getName().equals(methodName) || (method.getName() + "_COUNT").equals(methodName))) {return dataScopeFilter(annotation.dataScope(), annotation.deptAlias(), annotation.deptIdColumnName(), annotation.userAlias(), annotation.userIdColumnName(), where);}}return where;}/*** 构建过滤条件** @param where 当前查询条件* @return 构建后查询条件*/@SneakyThrowspublic static Expression dataScopeFilter(DataPermissionEnum dataScopeEnum, String deptAlias, String deptIdColumnName, String userAlias, String userIdColumnName, Expression where) {String deptColumnName = StrUtil.isNotBlank(deptAlias) ? (deptAlias + StringPool.DOT + deptIdColumnName) : deptIdColumnName;String userColumnName = StrUtil.isNotBlank(userAlias) ? (userAlias + StringPool.DOT + userIdColumnName) : userIdColumnName;TspUserInfo tspUserInfo = ThreadContext.getSubject();if (dataScopeEnum == null) {String dataPermission = tspUserInfo.getDataPermission();// 获取当前用户的数据权限dataScopeEnum = DataPermissionEnum.getByCode(dataPermission);}//部门ID 包含多个部门,同一个用户的部门来源于用户组String orgCode = tspUserInfo.getOrgCode();String userId = tspUserInfo.getUserId();String acctOrgCode = tspUserInfo.getAcctOrgCode();List<String> dataPermissionOrgCodes = tspUserInfo.getDataPermissionOrgCodes();String appendSqlStr;switch (Objects.requireNonNull(dataScopeEnum)) {case Org: // appendSqlStr = deptColumnName + " in (" + orgCode + ")";appendSqlStr = deptColumnName + StringPool.EQUALS + orgCode;break;case Personal:appendSqlStr = userColumnName + StringPool.EQUALS + userId;break;case AcctOrg:appendSqlStr = userColumnName + StringPool.EQUALS + acctOrgCode;break;// 默认部门及子部门数据权限default:appendSqlStr = deptColumnName + " in (" + String.join(",", dataPermissionOrgCodes) + ")";break;}if (StrUtil.isBlank(appendSqlStr)) {return where;}Expression appendExpression = CCJSqlParserUtil.parseCondExpression(appendSqlStr);if (where == null) {return appendExpression;}return new AndExpression(where, appendExpression);}}
2. 就认为是拦截器没有起作用,后面同事大哥给了一个解决方法
@Slf4j public class SqlSessionFactoryBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof SqlSessionFactory) { //所有bean初始化之后都会进入这个方法,这个时候需要滤出需要的类型,比如这次就只需要拿到SqlSessionFactory类型的对象对其设置拦截器就行了SqlSessionFactory nowBean = (SqlSessionFactory) bean;nowBean.getConfiguration().addInterceptor(new RowVersionUpdateInterceptor());nowBean.getConfiguration().addInterceptor(setMybatisPlusInterceptor());}return bean; //完成后返回出去,可能直接进入容器,也可能会去执行其他的BeanPostProcessor}public MybatisPlusInterceptor setMybatisPlusInterceptor(){MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new DataPermissionInterceptor(new MyDataPermissionHandler()));return interceptor;} }
直接在注册Bean的时候,将SqlSessionFactory相关的bean都加上拦截器,然后再把SqlSessionFactoryBeanPostProcessor 注册到ioc中
@Configuration public class MybatisPlusConfig {@Beanpublic SqlSessionFactoryBeanPostProcessor sqlSessionFactoryBeanPostProcessor() {return new SqlSessionFactoryBeanPostProcessor();} }
3.可以解决问题,但是又不知道这个问题出在哪里,因为我之前都是这样配的,且重新搭建一个新的环境按照原来的方法依然可以,等我了解后问题,在来加更。。。。。。