mybatis攔截器實(shí)現(xiàn)通用權(quán)限字段添加的方法
實(shí)現(xiàn)效果
日常sql中直接使用權(quán)限字段實(shí)現(xiàn)權(quán)限內(nèi)數(shù)據(jù)篩選,無(wú)需入?yún)ⅲ苯邮褂?,使用形式為?br />
select * from crh_snp.channelinfo where short_code in (${commonEnBranchNo})
注意事項(xiàng)說(shuō)明
1、添加插件若使用xml形式mybatis可在配置文件中plugins標(biāo)簽中添加,本項(xiàng)目實(shí)際使用的為注解形式mybatis,需要通過(guò)SqlSessionFactoryBean代碼方式添加或者SqlSessionFactoryBean的xml配置形式,代碼在jar包中無(wú)法操作,只能使用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,本項(xiàng)目中配置進(jìn)行覆蓋,注意spring中同名類(lèi)后加載的會(huì)覆蓋先加載的類(lèi),需要保證本項(xiàng)目配置的類(lèi)后加載。spring配置文件掃描會(huì)先加載本工程項(xiàng)目bean,可通過(guò)新增額外的配置文件放在原配置文件后實(shí)現(xiàn)后加載,如
<context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:spring-beans.xml classpath*:spring-person.xml </param-value> </context-param>
3、注意添加的參數(shù)需要${}形式使用,#{}會(huì)經(jīng)過(guò)預(yù)編譯獲取到的sql參數(shù)為問(wèn)號(hào),無(wú)法直接替換
攔截器實(shí)現(xiàn)類(lèi)
@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及營(yíng)業(yè)部作通用字段放到sql中統(tǒng)一解析 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) {} /** * 通用權(quán)限字段添加,目前支持: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; } /** * 獲取當(dāng)前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重新設(shè)置到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; } }
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
基于Java代碼實(shí)現(xiàn)支付充值的通用流程
本文給大家分享一段java核心代碼實(shí)現(xiàn)支付充值的通用流程,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧2016-05-05JDK17、JDK19、JDK1.8輕松切換(無(wú)坑版,小白也可以看懂!)
在做不同的java項(xiàng)目時(shí)候,因項(xiàng)目需要很可能來(lái)回切換jdk版本,下面這篇文章主要介紹了JDK17、JDK19、JDK1.8輕松切換的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02Java中static修飾的靜態(tài)變量、方法及代碼塊的特性與使用
這篇文章主要介紹了Java中static修飾的靜態(tài)變量、方法及代碼塊的特性與使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04Java使用fill()數(shù)組填充的實(shí)現(xiàn)
這篇文章主要介紹了Java使用fill()數(shù)組填充的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01spring boot 下對(duì)JSON返回值去除null和空字段操作
這篇文章主要介紹了spring boot 下對(duì)JSON返回值去除null和空字段操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10Spring Cloud Feign的文件上傳實(shí)現(xiàn)的示例代碼
這篇文章主要介紹了Spring Cloud Feign的文件上傳實(shí)現(xiàn)的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03