mybatis攔截器及不生效的解決方法
背景:
在一些需求下,使用攔截器會(huì)大大簡(jiǎn)化工作量也更加靈活:
- 在項(xiàng)目中,要更新數(shù)據(jù)表的審計(jì)字段,比如 create_time, creator, update_time, updator, 這些字段,如果每一個(gè)表對(duì)應(yīng)的mapper 都去寫(xiě)一次,或每一個(gè)方法都去更新一下,這個(gè)工作量非常大并且不太友好,并且不夠優(yōu)雅。
- 記錄一些日志,比如執(zhí)行sql時(shí)侯,要打印每一個(gè)sql執(zhí)行了多久,那就要記錄sql執(zhí)行前的時(shí)間戳,執(zhí)行后的時(shí)間戳,得到其執(zhí)行時(shí)間,再打印。
- 等等場(chǎng)景
在這些場(chǎng)景下,使用攔截器肯定會(huì)更加靈活且方法。
mybatis攔截器怎樣做
- 定義一個(gè)攔截器
- 把這個(gè)攔截器交給spring容器管理
- 如果項(xiàng)目里面使用了 com.github.pagehelper.PageInterceptor 攔截器可能會(huì)無(wú)效,則需要再定義一個(gè) MybatisInterceptorAutoConfiguration
根據(jù)以上三點(diǎn),進(jìn)行詳細(xì)說(shuō)明
定義一個(gè)攔截器
簡(jiǎn)單示意一下怎樣寫(xiě)。。。具體業(yè)務(wù)肯定不止這樣子的
一個(gè)攔截器,主要是實(shí)現(xiàn) Interceptor 這個(gè)接口,實(shí)現(xiàn)這個(gè)接口下的三個(gè)方法。
然后在這個(gè)實(shí)現(xiàn)類加上 @Component 注解,就交給 spring容器管理了,所以1,2是一起的
import org.apache.ibatis.cache.CacheKey; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import org.springframework.stereotype.Component; import java.util.Properties; import lombok.extern.slf4j.Slf4j; @Slf4j @Component @Intercepts({ @Signature( method = "query", type = Executor.class, args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class} ), @Signature( method = "query", type = Executor.class, args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class} ), @Signature( type = Executor.class, method = "update", args = {MappedStatement.class, Object.class} ) }) public class LogInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { log.info("begin >>>>>>>>>"); Object rest = invocation.proceed(); log.info("end >>>>>>>>>"); return rest; } @Override public Object plugin(Object o) { return Plugin.wrap(o, this); } @Override public void setProperties(Properties properties) { } }
定義一個(gè) MybatisInterceptorAutoConfiguration
為什么要有這么一個(gè)類呢,主要是因?yàn)槿绻愕哪K里面引用了 com.github.pagehelper.PageInterceptor,你自定義的攔截器會(huì)無(wú)效,是因?yàn)閙ybatis的攔截器這就是一個(gè)責(zé)任鏈,但是如果執(zhí)行了 PageInterceptor,這個(gè)Interceptor比較特別,它自己執(zhí)行完,就不往下傳遞鏈條了,即這個(gè)鏈會(huì)在它這里斷開(kāi)。所以加了其它的interceptor, 它們必須在 PageInterceptor 之前執(zhí)行。
具體可見(jiàn)代碼:
import com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration; import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.context.annotation.Configuration; @Configuration // 這一行很重要,因?yàn)閕nterceptor 鏈的執(zhí)行與添加是反序的,所以在 PageHelperAutoConfiguration 之后添加,才能先執(zhí)行。 @AutoConfigureAfter(PageHelperAutoConfiguration.class) public class MybatisInterceptorAutoConfiguration { @Autowired private List<SqlSessionFactory> sqlSessionFactoryList; @PostConstruct public void addMyInterceptor() { LogInterceptor e = new LogInterceptor(); for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) { sqlSessionFactory.getConfiguration().addInterceptor(e); } } }
附錄幾個(gè)參考的博文:
Mybatis攔截器
PageHelper導(dǎo)致自定義Mybatis攔截器不生效
Mybatis攔截器失效
到此這篇關(guān)于mybatis攔截器及不生效的解決方法的文章就介紹到這了,更多相關(guān)mybatis攔截器及不生效內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springboot項(xiàng)目啟動(dòng)時(shí)如何用命令動(dòng)態(tài)指定環(huán)境
這篇文章主要介紹了Springboot項(xiàng)目啟動(dòng)時(shí)如何用命令動(dòng)態(tài)指定環(huán)境的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06java實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06java基礎(chǔ)篇之Date類型最常用的時(shí)間計(jì)算(相當(dāng)全面)
這篇文章主要給大家介紹了關(guān)于java基礎(chǔ)篇之Date類型最常用的時(shí)間計(jì)算的相關(guān)資料,Java中的Date類是用來(lái)表示日期和時(shí)間的類,它提供了一些常用的方法來(lái)處理日期和時(shí)間的操作,需要的朋友可以參考下2023-12-12java數(shù)學(xué)工具類Math詳解(round方法)
這篇文章主要為大家詳細(xì)介紹了java數(shù)學(xué)工具類Math,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08