实现效果

日常sql中直接使用权限字段实现权限内数据筛选,无需入参,直接使用,使用形式为:
select * from crh_snp.channelinfo where short_code in (${commonEnBranchNo})

注意事项说明

1、添加插件若使用xml形式mybatis可在配置文件中plugins标签中添加,本项目实际使用的为注解形式mybatis,需要通过SqlSessionFactoryBean代码方式添加或者SqlSessionFactoryBean的xml配置形式,代码在jar包中无法操作,只能使用xml配置形式,故需要覆盖SqlSessionFactoryBean配置

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations">
<list>
<value>classpath*:xmlmapper/*.xml</value>
<value>classpath*:resources/xmlmapper/*.xml</value>
</list>
</property>
<property name="plugins">
<array>
<bean class="com.cairh.xpe.snp.backend.interceptor.MybatisInterceptor"/>
</array>
</property>
</bean>

2、jdbc的jar包中配置了sqlSessionFactory,本项目中配置进行覆盖,注意spring中同名类后加载的会覆盖先加载的类,需要保证本项目配置的类后加载。spring配置文件扫描会先加载本工程项目bean,可通过新增额外的配置文件放在原配置文件后实现后加载,如

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:spring-beans.xml
classpath*:spring-person.xml
</param-value>
</context-param>

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<String> 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. jQuery导入Eclipse后报错解决方法
  2. 建站技能get(1)— Asp.net MVC快速集成ckplayer网页视频播放器
  3. 计算机网络(8)-----TCP报文段的首部格式
  4. HTTP POST, PUT PATCH
  5. ios开发者证书 签发者无效
  6. autorelease 的基本使用
  7. SQLLite 简介
  8. maven发布时在不同的环境使用不同的配置文件
  9. 生成html文件
  10. C语言的本质(14)——不完全类型和复杂声明
  11. JAVA课程设计+五子棋(团队博客)
  12. JS表格分页(封装版)
  13. Assembly.LoadFrom加载程序集类型转换失败解决方法
  14. js中采用词法作用域
  15. Android数据存储五种方式
  16. MDX Cookbook 08 - 基于集合上的迭代递归
  17. MVC ---- EF三层代码
  18. Ubuntu软件更新时出错问题解决
  19. 转:linux的fatab文件详解
  20. 浅谈ASP.net中的DataSet对象

热门文章

  1. 带你剖析WebGis的世界奥秘----瓦片式加载地图
  2. MQTT的学习之Mosquitto安装和使用
  3. Python自动化开发
  4. spring-boot-plus集成Spring Boot Admin管理和监控应用(十一)
  5. [HEOI2013]SAO(树上dp,计数)
  6. 第 10 篇:小细节 Markdown 文章自动生成目录,提升阅读体验
  7. 在win10中安装python3.6.6
  8. TortoiseGit的NetWork中的Enale proxy Server的作用
  9. LSTM 反向传播算法
  10. MVC整体运行流程一(进入管道)