MyBatis Excutor 攔截器的巧妙用法
這里要講的巧妙用法是用來實現在攔截器中執(zhí)行額外 MyBatis 現有方法的用法。
并且會提供一個解決攔截Executor時想要修改MappedStatement時解決并發(fā)的問題。
這里假設一個場景:
實現一個攔截器,記錄 MyBatis 所有的 insert,update,delete 操作,將記錄的信息存入數據庫。
這個用法在這里就是將記錄的信息存入數據庫。
實現過程的關鍵步驟和代碼:
1.首先在某個 Mapper.xml 中定義好了一個往日志表中插入記錄的方法,假設方法為id="insertSqlLog"。
2.日志表相關的實體類為SqlLog.
3.攔截器簽名:
@Intercepts({@org.apache.ibatis.plugin.Signature( type=Executor.class, method="update", args={MappedStatement.class, Object.class})}) public class SqlInterceptor implements Interceptor
4.接口方法簡單實現:
public Object intercept(Invocation invocation) throws Throwable { Object[] args = invocation.getArgs(); MappedStatement ms = (MappedStatement) args[0]; Object parameter = args[1]; SqlLog log = new SqlLog(); Configuration configuration = ms.getConfiguration(); Object target = invocation.getTarget(); StatementHandler handler = configuration.newStatementHandler((Executor) target, ms, parameter, RowBounds.DEFAULT, null, null); BoundSql boundSql = handler.getBoundSql(); //記錄SQL log.setSqlclause(boundSql.getSql()); //執(zhí)行真正的方法 Object result = invocation.proceed(); //記錄影響行數 log.setResult(Integer.valueOf(Integer.parseInt(result.toString()))); //記錄時間 log.setWhencreated(new Date()); //TODO 還可以記錄參數,或者單表id操作時,記錄數據操作前的狀態(tài) //獲取insertSqlLog方法 ms = ms.getConfiguration().getMappedStatement("insertSqlLog"); //替換當前的參數為新的ms args[0] = ms; //insertSqlLog 方法的參數為 log args[1] = log; //執(zhí)行insertSqlLog方法 invocation.proceed(); //返回真正方法執(zhí)行的結果 return result; }
重點
MappedStatement是一個共享的緩存對象,這個對象是存在并發(fā)問題的,所以幾乎任何情況下都不能去修改這個對象(通用Mapper除外),想要對MappedStatement做修改該怎么辦呢?
并不難,Executor中的攔截器方法參數中都有MappedStatement ms,這個ms就是后續(xù)方法執(zhí)行要真正用到的MappedStatement,這樣一來,問題就容易解決了,根據自己的需要,深層復制MappedStatement對象中自己需要修改的屬性,然后修改這部分屬性,之后將修改后的ms通過上面代碼中args[0]=ms這種方式替換原有的參數,這樣就能實現對ms的修改而且不會有并發(fā)問題了。
這里日志的例子就是一個更簡單的應用,并沒有創(chuàng)建ms,只是獲取了一個新的ms替換現有的ms,然后去執(zhí)行。
總結
以上所述是小編給大家介紹的MyBatis Excutor 攔截器的巧妙用法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
相關文章
nacos gateway動態(tài)路由實戰(zhàn)
這篇文章主要介紹了nacos gateway動態(tài)路由實戰(zhàn),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09mybatis教程之查詢緩存(一級緩存二級緩存和整合ehcache)
這篇文章主要介紹了mybatis教程之查詢緩存(一級緩存二級緩存和整合ehcache),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05Java設計模式之觀察者模式(Observer Pattern)詳解
觀察者模式(Observer Pattern)是一種行為型設計模式,它定義了一種一對多的依賴關系,當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都能夠自動地得到通知并進行更新,本文將詳細的給大家介紹一下Java觀察者模式,需要的朋友可以參考下2023-07-07詳解在SpringBoot中使用MongoDb做單元測試的代碼
這篇文章主要介紹了詳解在SpringBoot中使用MongoDb做單元測試的代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11