mybatis拦截器怎么实现通用权限字段添加功能
创始人
2024-12-22 17:41:38
0次

实现效果

日常sql中直接使用权限字段实现权限内数据筛选,无需入参,直接使用,使用形式为:

select * from crh_snp.channelinfo where short_code in (${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})})public class MybatisInterceptor implements Interceptor {//  private Logger logger = LoggerFactory.getLogger(getClass());  @Override  public Object intercept(Invocation invocation) throws Throwable {    if (invocation.getTarget() instanceof Executor && invocation.getArgs().length==4) {      String sql = getSqlByInvocation(invocation);      //将操作员可操作的渠道、用户id及营业部作通用字段放到sql中统一解析      if(sql.contains("commonEnShortCode")){        sql = addPremissionParam(sql);        resetSql2Invocation(invocation, sql);      }    }    return invocation.proceed();  }  @Override  public Object plugin(Object target) {    return Plugin.wrap(target, this);  }  @Override  public void setProperties(Properties properties) {}  /**   * 通用权限字段添加,目前支持:commonEnShortCode、commonEnBrokerUserId、commonEnBranchNo   * @param sql   * @return   */  private String addPremissionParam(String sql) {    CrhUser crhUser = (CrhUser) RequestUtil.getRequest().getAttribute(CrhUser.CRH_USER_SESSION);    BackendRoleServiceImpl backendRoleService = (BackendRoleServiceImpl)SpringContext.getBean("backendRoleServiceImpl");    if(sql.contains("commonEnBranchNo")){      List enBranchNoList = backendRoleService.getEnBranchNo(crhUser.getUser_id());      String enBranchNoSql = "select to_char(column_value) from TABLE(SELECT F_TO_T_IN('"+ StringUtils.join(enBranchNoList,",")+"') FROM DUAL)";      sql = sql.replace("${commonEnBranchNo}", enBranchNoSql);    }    return sql;  }  /**   * 获取当前sql   * @param invocation   * @return   */  private String getSqlByInvocation(Invocation invocation) {    final Object[] args = invocation.getArgs();    MappedStatement ms = (MappedStatement) args[0];    Object parameterObject = args[1];    BoundSql boundSql = ms.getBoundSql(parameterObject);    return boundSql.getSql();  }  /**   * 将sql重新设置到invocation中   * @param invocation   * @param sql   * @throws SQLException   */  private void resetSql2Invocation(Invocation invocation, String sql) throws SQLException {    final Object[] args = invocation.getArgs();    MappedStatement statement = (MappedStatement) args[0];    Object parameterObject = args[1];    BoundSql boundSql = statement.getBoundSql(parameterObject);    MappedStatement newStatement = newMappedStatement(statement, new BoundSqlSource(boundSql));    MetaObject msObject = MetaObject.forObject(newStatement, new DefaultObjectFactory(), new DefaultObjectWrapperFactory(),new DefaultReflectorFactory());    msObject.setValue("sqlSource.boundSql.sql", sql);    args[0] = newStatement;  }  private MappedStatement newMappedStatement(MappedStatement ms, SqlSource newSqlSource) {    MappedStatement.Builder builder =        new MappedStatement.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) {      StringBuilder keyProperties = new StringBuilder();      for (String keyProperty : 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());    return builder.build();  }}

public class BoundSqlSource implements SqlSource {  private BoundSql boundSql;  public BoundSqlSource(BoundSql boundSql) {    this.boundSql = boundSql;  }  @Override  public BoundSql getBoundSql(Object parameterObject) {    return boundSql;  }}

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...