大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
上一篇中讲了mybatis拦截器的实现
这一篇扩展mybatis在拦截器中添加额外参数
在mybatis的mapper.xml文件中,我们可以使用#{}或${}的方式获取到参数,这些参数都需要提前我们在mapper.java接口文件中通过参数的方式传入参数才能取到
为了扩展参数,我们需要了解mybatis是怎么帮我们保管mapper.java中传入的参数的
进入Executor.java接口查看query方法,可以看到第一个参数MappedStatement对象中有一个parameterMap字段,该字段是Map类型保存我们的参数,那我们只需要在拦截器中对MappedStatement对象的parameterMap中put自己想要的参数即可
代码如下
/** * 部门数据拦截器 * * @author zhangxing * @date 2021/4/12 */
@Intercepts({
@Signature(type = Executor.class, method = "query", args = {
MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
@Signature(type = Executor.class, method = "query", args = {
MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})
})
public class DeptDataScopeInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
if (ArrayUtils.isNotEmpty(args)) {
MappedStatement mappedStatement = (MappedStatement) args[0];
DataScope dataScope = getDataScope(mappedStatement);
StringBuilder sqlString = new StringBuilder();
if (dataScope != null) {
Long companyOrgId = SecurityUtils.getCompanyOrgId();
if (companyOrgId != null) {
sqlString.append(StringUtils.format(" {}.{} = {} ", dataScope.orgAlias(), dataScope.orgColumnName(), companyOrgId));
} else {
sqlString.append(" 1=0 ");
}
}
if (args[1] == null) {
args[1] = new MapperMethod.ParamMap<>();
}
Map map = (Map) args[1];
// 此处为重点
map.put("dataScope", sqlString.length() > 0 ? " (" + sqlString.toString() + ")" : "");
}
return invocation.proceed();
}
private DataScope getDataScope(MappedStatement mappedStatement) {
String id = mappedStatement.getId();
// 获取 Class Method
String clazzName = id.substring(0, id.lastIndexOf('.'));
String mapperMethod = id.substring(id.lastIndexOf('.') + 1);
Class<?> clazz;
try {
clazz = Class.forName(clazzName);
} catch (ClassNotFoundException e) {
return null;
}
Method[] methods = clazz.getMethods();
DataScope dataScope = null;
for (Method method : methods) {
if (method.getName().equals(mapperMethod)) {
dataScope = method.getAnnotation(DataScope.class);
break;
}
}
return dataScope;
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
}
在map中加入dataScope后,即可在相应的mapper.xml中使用#{dataScope}或${dataScope}或取到该参数
如果项目中使用了pageHelper插件,则启动项目后,执行到对应的mapper查询的时候,如果mapper.xml中使用了上述方式添加的参数,那么项目会报错,因为pageHelper的拦截器会在我们的拦截器之前执行,pageHelper的拦截器中对参数进行了校验,因为自定的拦截器还没有执行,则Map中不会有自定义参数,当pageHelper的拦截器开始校验参数的时候就会报错找不到参数
如何将自定义的拦截器放在PageHelper拦截器前方执行
查阅资料后发现SqlSessionFactory中加入的拦截器,先加入的会后执行,后加入的先执行,那么我们需要让自定义的拦截器在PageHelper后加入,查看PageHelper的自动配置类
pageHelper的拦截器会在Mybatis的自动配置后在做相应配置,那么我们可以写一个配置类,让他在PageHelper的配置类后再执行
代码如下
/** * @author zhangxing * @date 2021/4/11 */
@Configuration
@ConditionalOnBean({
SqlSessionFactory.class})
@AutoConfigureAfter(PageHelperAutoConfiguration.class)
public class DeptDataScopeInterceptorConfig {
@Autowired
private List<SqlSessionFactory> sqlSessionFactoryList;
@PostConstruct
public void addPageInterceptor() {
DeptDataScopeInterceptor interceptor = new DeptDataScopeInterceptor();
for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
sqlSessionFactory.getConfiguration().addInterceptor(interceptor);
}
}
}
此处需要注意的是,如果DeptDataScopeInterceptorConfig
配置类会被SpringBoot项目自动扫描到,尽管配置的顺序是在PageHelper自动配置后再配置,但是被SpringBoot扫描到的配置类会优先加载,所以要防止SpringBoot扫描带该配置,有如下几种方案
- 如果该配置类已经会被扫描到,则可以使用排出的方式排除掉该类,然后用spring.factories的方式做自动配置
可以使用@SpringBootApplication(exclude = DeptDataScopeInterceptorConfig.class)
或@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = DeptDataScopeInterceptorConfig.class))
或@EnableAutoConfiguration(exclude = DeptDataScopeInterceptorConfig.class)
的方式排出,然后添加到spring.factories中
文件路径地址resrouces/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
top.sclf.common.datascope.config.DeptDataScopeInterceptorConfig
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/197765.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...