mybatis攔截器實(shí)現(xiàn)通用權(quán)限字段添加的方法
實(shí)現(xiàn)效果
日常sql中直接使用權(quán)限字段實(shí)現(xiàn)權(quán)限內(nèi)數(shù)據(jù)篩選,無需入?yún)?,直接使用,使用形式為?br />
select * from crh_snp.channelinfo where short_code in (${commonEnBranchNo})
注意事項(xiàng)說明
1、添加插件若使用xml形式mybatis可在配置文件中plugins標(biāo)簽中添加,本項(xiàng)目實(shí)際使用的為注解形式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,本項(xiàng)目中配置進(jìn)行覆蓋,注意spring中同名類后加載的會覆蓋先加載的類,需要保證本項(xiàng)目配置的類后加載。spring配置文件掃描會先加載本工程項(xiàng)目bean,可通過新增額外的配置文件放在原配置文件后實(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ù)需要${}形式使用,#{}會經(jīng)過預(yù)編譯獲取到的sql參數(shù)為問號,無法直接替換
攔截器實(shí)現(xiàn)類
@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è)部作通用字段放到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é)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。
相關(guān)文章
idea批量啟動多個微服務(wù)具體實(shí)現(xiàn)
這篇文章主要給大家介紹了關(guān)于idea批量啟動多個微服務(wù)的具體實(shí)現(xiàn),在微服務(wù)開發(fā)過程中,我們經(jīng)常要在本地啟動很多個微服務(wù),文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07
JavaMail整合Spring實(shí)現(xiàn)郵件發(fā)送功能
這篇文章主要為大家詳細(xì)介紹了JavaMail整合Spring實(shí)現(xiàn)郵件發(fā)送功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
java對接微信小程序詳細(xì)流程(登錄&獲取用戶信息)
這篇文章主要給大家介紹了關(guān)于java對接微信小程序(登錄&獲取用戶信息)的相關(guān)資料,我們在開發(fā)微信小程序時(shí)經(jīng)常需要獲取用戶微信用戶名以及頭像信息,微信提供了專門的接口API用于返回這些信息,需要的朋友可以參考下2023-08-08
Java并發(fā)編程之常用的多線程實(shí)現(xiàn)方式分析
這篇文章主要介紹了Java并發(fā)編程之常用的多線程實(shí)現(xiàn)方式,結(jié)合實(shí)例形式分析了java并發(fā)編程中多線程的相關(guān)原理、實(shí)現(xiàn)方法與操作注意事項(xiàng),需要的朋友可以參考下2020-02-02
基于Java實(shí)現(xiàn)修改圖片分辨率示例代碼
這篇文章主要介紹了一個可以修改圖片分辨率的java工具類,文中的示例代碼講解詳細(xì),對學(xué)習(xí)JAVA有一定的幫助,感興趣的小伙伴快來跟隨小編一起學(xué)習(xí)吧2021-12-12
Java設(shè)計(jì)模式之外觀模式的實(shí)現(xiàn)方式
這篇文章主要介紹了Java設(shè)計(jì)模式之外觀模式的實(shí)現(xiàn)方式,外觀模式隱藏系統(tǒng)的復(fù)雜性,并向客戶端提供了一個客戶端可以訪問系統(tǒng)的接口,這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它向現(xiàn)有的系統(tǒng)添加一個接口,來隱藏系統(tǒng)的復(fù)雜性,需要的朋友可以參考下2023-11-11

