回覆列表
  • 1 # 程式設計師米兜

    01前言

    由於mybatis提供也提供了外掛這個擴充套件,很多的思路就是在外掛上做文章,在github上也的確有這樣的倉庫。

    基於Executor:

    https://github.com/miaoxinwei/mybatis-crypt

    基於StatementHandler:

    https://github.com/ikchan/mybatis-plugin-cryptogram

    02正文

    這兩個分別是基於Executor和StatementHandler做的外掛,這裡不介紹怎麼實現一個mybatis外掛,有興趣的可以看下官網。

    mybatis外掛plugins demo:

    http://www.mybatis.org/mybatis-3/zh/configuration.html#plugins

    分別可以對以下4種情況就行擴充套件:

    ParameterHandler (getParameterObject, setParameters),aop setParameters是不行的,因為這時已經完成了sql解析,某些取值已經不會再透過原始的parameter取值。比如:如果時foreach標籤,在此時會通boundSql.getAdditionalParameter獲取

    StatementHandler (prepare, parameterize, batch, update, query),這裡也是做不了的,因為已經失去了屬性註解相關的資訊

    ResultSetHandler (handleResultSets, handleOutputParameters) 這個可以做結果集解密。

    Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) 這個當然是可以的,他就是查詢的出入口

    所以在對資料做加減密的外掛時,選擇對Executor做。

    這裡就實現一個基於Executor的Interceptor。在看到上面基於Executor實現時候,總感覺有些彆扭,

    一是沒有將方法元資料與加解密分開,二是太多if else判斷在做加解密流程中。

    新的實現將intercept方法分為以下4步

    public Object intercept(Invocation invocation) throws Throwable {

    Object[] args = invocation.getArgs();

    // 1.獲取方法加解密 元資料

    MethodCryptMetadata methodCryptMetadata = getCachedMethodCryptMetaData((MappedStatement) args[0]);

    // 2.加密

    args[1] = methodCryptMetadata.encrypt(args[1]);

    // 3.執行sql

    Object returnValue = invocation.proceed();

    // 4.解密

    return methodCryptMetadata.decrypt(returnValue);

    }

    特殊說明

    encryptWithOutAnnotation,decryptWithOutAnnotation可以透過外掛properties修改

    程式碼中XXX標記的是特殊說明

    關於bean的加密,會涉及到原物件的修改,程式碼中透過clone避免

    為避免多處對null值就行判斷,handler和executor等都加了Null的實現

    MethodMetadata中的兩個Resolver可能有一定的過度設計的嫌疑,主要是為了減少if else判斷

    03最後

    類圖、序列圖:

    具體實現可見原始碼:

    https://github.com/StarskyBoy/mybatis-crypt

  • 中秋節和大豐收的關聯?
  • C30混凝土水池牆板和底板拆模時間一般是澆築幾天後按規定?