mybatis拦截器实现通用权限字段添加的方法
实现效果
日常sql中直接使用权限字段实现权限内数据筛选,无需入参,直接使用,使用形式为:
select*fromcrh_snp.channelinfowhereshort_codein(${commonEnBranchNo})
注意事项说明
1、添加插件若使用xml形式mybatis可在配置文件中plugins标签中添加,本项目实际使用的为注解形式mybatis,需要通过SqlSessionFactoryBean代码方式添加或者SqlSessionFactoryBean的xml配置形式,代码在jar包中无法操作,只能使用xml配置形式,故需要覆盖SqlSessionFactoryBean配置
classpath*:xmlmapper/*.xml classpath*:resources/xmlmapper/*.xml
2、jdbc的jar包中配置了sqlSessionFactory,本项目中配置进行覆盖,注意spring中同名类后加载的会覆盖先加载的类,需要保证本项目配置的类后加载。spring配置文件扫描会先加载本工程项目bean,可通过新增额外的配置文件放在原配置文件后实现后加载,如
contextConfigLocation classpath*:spring-beans.xml classpath*:spring-person.xml
3、注意添加的参数需要${}形式使用,#{}会经过预编译获取到的sql参数为问号,无法直接替换
拦截器实现类
@Intercepts({
@Signature(type=Executor.class,method="query",args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class})
})
publicclassMybatisInterceptorimplementsInterceptor{
//privateLoggerlogger=LoggerFactory.getLogger(getClass());
@Override
publicObjectintercept(Invocationinvocation)throwsThrowable{
if(invocation.getTarget()instanceofExecutor&&invocation.getArgs().length==4){
Stringsql=getSqlByInvocation(invocation);
//将操作员可操作的渠道、用户id及营业部作通用字段放到sql中统一解析
if(sql.contains("commonEnShortCode")){
sql=addPremissionParam(sql);
resetSql2Invocation(invocation,sql);
}
}
returninvocation.proceed();
}
@Override
publicObjectplugin(Objecttarget){
returnPlugin.wrap(target,this);
}
@Override
publicvoidsetProperties(Propertiesproperties){}
/**
*通用权限字段添加,目前支持:commonEnShortCode、commonEnBrokerUserId、commonEnBranchNo
*@paramsql
*@return
*/
privateStringaddPremissionParam(Stringsql){
CrhUsercrhUser=(CrhUser)RequestUtil.getRequest().getAttribute(CrhUser.CRH_USER_SESSION);
BackendRoleServiceImplbackendRoleService=(BackendRoleServiceImpl)SpringContext.getBean("backendRoleServiceImpl");
if(sql.contains("commonEnBranchNo")){
ListenBranchNoList=backendRoleService.getEnBranchNo(crhUser.getUser_id());
StringenBranchNoSql="selectto_char(column_value)fromTABLE(SELECTF_TO_T_IN('"+StringUtils.join(enBranchNoList,",")+"')FROMDUAL)";
sql=sql.replace("${commonEnBranchNo}",enBranchNoSql);
}
returnsql;
}
/**
*获取当前sql
*@paraminvocation
*@return
*/
privateStringgetSqlByInvocation(Invocationinvocation){
finalObject[]args=invocation.getArgs();
MappedStatementms=(MappedStatement)args[0];
ObjectparameterObject=args[1];
BoundSqlboundSql=ms.getBoundSql(parameterObject);
returnboundSql.getSql();
}
/**
*将sql重新设置到invocation中
*@paraminvocation
*@paramsql
*@throwsSQLException
*/
privatevoidresetSql2Invocation(Invocationinvocation,Stringsql)throwsSQLException{
finalObject[]args=invocation.getArgs();
MappedStatementstatement=(MappedStatement)args[0];
ObjectparameterObject=args[1];
BoundSqlboundSql=statement.getBoundSql(parameterObject);
MappedStatementnewStatement=newMappedStatement(statement,newBoundSqlSource(boundSql));
MetaObjectmsObject=MetaObject.forObject(newStatement,newDefaultObjectFactory(),newDefaultObjectWrapperFactory(),newDefaultReflectorFactory());
msObject.setValue("sqlSource.boundSql.sql",sql);
args[0]=newStatement;
}
privateMappedStatementnewMappedStatement(MappedStatementms,SqlSourcenewSqlSource){
MappedStatement.Builderbuilder=
newMappedStatement.Builder(ms.getConfiguration(),ms.getId(),newSqlSource,ms.getSqlCommandType());
builder.resource(ms.getResource());
builder.fetchSize(ms.getFetchSize());
builder.statementType(ms.getStatementType());
builder.keyGenerator(ms.getKeyGenerator());
if(ms.getKeyProperties()!=null&&ms.getKeyProperties().length!=0){
StringBuilderkeyProperties=newStringBuilder();
for(StringkeyProperty:ms.getKeyProperties()){
keyProperties.append(keyProperty).append(",");
}
keyProperties.delete(keyProperties.length()-1,keyProperties.length());
builder.keyProperty(keyProperties.toString());
}
builder.timeout(ms.getTimeout());
builder.parameterMap(ms.getParameterMap());
builder.resultMaps(ms.getResultMaps());
builder.resultSetType(ms.getResultSetType());
builder.cache(ms.getCache());
builder.flushCacheRequired(ms.isFlushCacheRequired());
builder.useCache(ms.isUseCache());
returnbuilder.build();
}
}
publicclassBoundSqlSourceimplementsSqlSource{
privateBoundSqlboundSql;
publicBoundSqlSource(BoundSqlboundSql){
this.boundSql=boundSql;
}
@Override
publicBoundSqlgetBoundSql(ObjectparameterObject){
returnboundSql;
}
}
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。