Mybatis自定義插件Interceptor問題
Mybatis自定義插件-Interceptor
MyBatis允許你在映射語句執(zhí)行過程中的某一點(diǎn)進(jìn)行攔截調(diào)用。
默認(rèn)情況下,MyBatis 允許使用插件來攔截的方法調(diào)用包括:
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
ParameterHandler (getParameterObject, setParameters)
ResultSetHandler (handleResultSets, handleOutputParameters)
StatementHandler (prepare, parameterize, batch, update, query)
這些類中方法的細(xì)節(jié)可以通過查看每個(gè)方法的簽名來發(fā)現(xiàn),或者直接查看 MyBatis 發(fā)行包中的源代碼。 如果你想做的不僅僅是監(jiān)控方法的調(diào)用,那么你最好相當(dāng)了解要重寫的方法的行為。 因?yàn)樵谠噲D修改或重寫已有方法的行為時(shí),很可能會(huì)破壞 MyBatis 的核心模塊。 這些都是更底層的類和方法,所以使用插件的時(shí)候要特別當(dāng)心。
通過 MyBatis 提供的強(qiáng)大機(jī)制,使用插件是非常簡單的,只需實(shí)現(xiàn) Interceptor 接口,并指定想要攔截的方法簽名即.
@Intercepts(value = {@Signature(
? ? ? ? type = Executor.class,
? ? ? ? method = "query",
? ? ? ? args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class MyInterceptor implements Interceptor {
? ? // ? ?@Autowired
? ? private Logger log = new LoggerStudoImpl();
? ? @Override
? ? public Object intercept(Invocation invocation) throws Throwable {
? ? ? ? // 該方法寫入自己的邏輯
? ? ? ? Object[] queryArgs = invocation.getArgs();
? ? ? ? MappedStatement ms = (MappedStatement) queryArgs[0];
? ? ? ? BoundSql boundSql = ms.getBoundSql(queryArgs[1]);
? ? ? ? String sql = boundSql.getSql();
? ? ? ? String SQL = new StringBuilder(sql).append(" ").append("and deleted = '0'").toString();
? ? ? ? StaticSqlSource rawSqlSource = new StaticSqlSource(ms.getConfiguration(), SQL, boundSql.getParameterMappings());
? ? ? ? MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), rawSqlSource, 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) {
? ? ? ? ? ? builder.keyProperty(ms.getKeyProperties()[0]);
? ? ? ? }
? ? ? ? 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());
? ? ? ? MappedStatement statement = builder.build();
? ? ? ? queryArgs[0] = statement;
? ? ? ? log.error(SQL);
? ? ? ? return invocation.proceed();
? ? }
? ? @Override
? ? public Object plugin(Object target) {
? ? ? ? return Plugin.wrap(target, this);
? ? }
? ? @Override
? ? public void setProperties(Properties properties) {
? ? }
}然后將自定義插件添加到Mybatis配置文件中,該插件就會(huì)生效。
? ?<plugins> ? ? ? ? <plugin interceptor="com.example.shiro.config.MyInterceptor"></plugin> ? ? </plugins>
自定義插件攔截的是Excutor中的query方法,也就是說只要是Mybatis執(zhí)行查詢,那么該插件就會(huì)攔截查詢的SQL語句,將查詢的SQL添加上and deleted = ‘0’,這樣每次查詢就無需加上deleted='0’了。
比如一些分頁插件就是攔截的ReultSetHandle進(jìn)而將查詢的結(jié)果進(jìn)行分頁處理。
Mybatis Interceptor插件開發(fā)總結(jié)
Interviewceptor插件開發(fā)的demo先記錄下,mybatis的加載過程和執(zhí)行過程下次再補(bǔ)上
package com.syygl.test.study.mybatis;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.plugin.*;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
*type=
* Executor 攔截執(zhí)行器的方法
* ParameterHandler 攔截參數(shù)的處理
* ResultSetHandler 攔截結(jié)果集的處理
* StatementHandler 攔截Sql語法構(gòu)建的處理
*
* method的值是以上四個(gè)接口中的method
*
* args的值是method的參數(shù)
*
*/
@Intercepts(
{
@Signature(type = Executor.class, method = "query", args = {})
}
)
public class InterceptorTest implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
//Invocation是type中指定要攔截的對(duì)象 ---調(diào)用
//proceed ---繼續(xù)
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
//是要攔截的對(duì)象才會(huì)進(jìn)入處理方案
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
}
/**
* MybatisConfig用來將自定義的Interceptor添加進(jìn)去
*/
@Configuration
class MybatisConfig {
@Bean
ConfigurationCustomizer mybatisConfigurationCustomizer() {
return new ConfigurationCustomizer() {
@Override
public void customize(org.apache.ibatis.session.Configuration configuration) {
configuration.addInterceptor(new InterceptorTest());
}
};
}
}
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot?mybatis-plus使用json字段實(shí)戰(zhàn)指南
在現(xiàn)代應(yīng)用開發(fā)中經(jīng)常會(huì)使用JSON格式存儲(chǔ)和傳輸數(shù)據(jù),為了便捷地處理數(shù)據(jù)庫中的JSON字段,MyBatis-Plus提供了強(qiáng)大的JSON處理器,這篇文章主要給大家介紹了關(guān)于SpringBoot?mybatis-plus使用json字段的相關(guān)資料,需要的朋友可以參考下2024-01-01
JavaWeb學(xué)習(xí)筆記之Filter和Listener
這篇文章主要給大家介紹了關(guān)于JavaWeb學(xué)習(xí)筆記之Filter和Listener的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Spring Task定時(shí)任務(wù)的實(shí)現(xiàn)詳解
這篇文章主要介紹了SpringBoot定時(shí)任務(wù)功能詳細(xì)解析,這次的功能開發(fā)過程中也算是對(duì)其內(nèi)涵的進(jìn)一步了解,以后遇到定時(shí)任務(wù)的處理也更清晰,更有效率了,對(duì)SpringBoot定時(shí)任務(wù)相關(guān)知識(shí)感興趣的朋友一起看看吧2022-08-08
利用Redis實(shí)現(xiàn)延時(shí)處理的方法實(shí)例
這篇文章主要給大家介紹了關(guān)于利用Redis實(shí)現(xiàn)延時(shí)處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用Redis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
springboot themaleaf 第一次進(jìn)頁面不加載css的問題
這篇文章主要介紹了springboot themaleaf 第一次進(jìn)頁面不加載css的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10

