mybatis拦截器实现通用权限字段添加的方法
时间:2019-09-18
本文章向大家介绍mybatis拦截器实现通用权限字段添加的方法,主要包括mybatis拦截器实现通用权限字段添加的方法使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
实现效果
日常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; } }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。
- 微信公众号复制的图片可以正常显示的办法
- 不明恶意攻击致<搜狗搜索><搜索结果>跳转<百度搜索>技术原理分析
- Struts2 S2-052 RCE简单测试
- javaScript实现归并排序
- js粘贴事件paste简单解析及遇到的坑
- 学习zepto.js(对象方法)[6]
- Javascript 装饰器极速指南
- daterangepicker日历插件使用参数注意问题
- 学习zepto.js(对象方法)[5]
- js 停止事件冒泡 阻止浏览器的默认行为
- vue-cli生成的项目配置开发和生产环境不同的接口
- 【52ABP实战教程】0.1-- Devops如何用VSTS持续集成到Github仓库!
- 学习zepto.js(对象方法)[4]
- 事件绑定的几种常见方式
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python读取图像矩阵文件并转换为向量实例
- PHP echo()函数讲解
- Python3开发环境搭建详细教程
- php使用QueryList轻松采集js动态渲染页面方法
- PHP convert_uudecode()函数讲解
- php实现在线考试系统【附源码】
- 实例介绍PHP中zip_open()函数用法
- php实现数字补零的方法总结
- PHP配置ZendOpcache插件加速
- 详解php用static方法的原因
- phpinfo无法显示的原因及解决办法
- 在php的yii2框架中整合hbase库的方法
- PHP安装memcache扩展的步骤讲解
- python退出循环的方法
- PHP crypt()函数的用法讲解