非常に強力なプラグインをMyBatisのは、SQL文、パラメータ注入、それぞれが一般的に検査し、アクセス制御注入を含め、結果セットと他の主要分野を返し、読み取り専用データベースから書き換えられ、介入するSQLの実行に私たちが侵入しませせることができますマッピング、K / V変換、動的SQLを書き換えます。
MyBatisの4ラージ・オブジェクト(エグゼキュータ、StatementHandler、ParameterHandler、ResultSetHandler)に特異的な支持体上にメソッドインターセプトを実行するためのデフォルトの方法をサポートしています。
- エグゼキュータ(更新、クエリ、flushStatements、コミット、ロールバック、getTransaction、近い、閉じられ)
- ParameterHandler(getParameterObject、setParametersを使用)
- ResultSetHandler(handleResultSets、handleOutputParameters)
- StatementHandler(バッチ、更新、照会、準備パラメータ化)
具体的な方法は、開始ここでは詳細に説明されていない、すべてのクラスメソッドのシグネチャの定義に見つけることができます。これらの4つのクラスが作成された後、直接戻らないが、実行作成戻す前にinterceptorChain.pluginAll(parameterHandlerを)。次のように:
// 設定中 公共ParameterHandler newParameterHandler(MappedStatement mappedStatement、parameterObject、BoundSql boundSqlオブジェクト){ ParameterHandler parameterHandler = mappedStatement.getLang()createParameterHandler(mappedStatement、parameterObject、boundSql)。 parameterHandler = (ParameterHandler)interceptorChain.pluginAll(parameterHandler)。 返すparameterHandlerを。 } 公共ResultSetHandler newResultSetHandler(エグゼキュータ、MappedStatement mappedStatement、RowBounds rowBounds、ParameterHandler parameterHandler、 ResultHandler resultHandler、BoundSql boundSql){ ResultSetHandler resultSetHandler = 新しいですDefaultResultSetHandler(エグゼキュータ、mappedStatement、parameterHandler、resultHandler、boundSql、rowBounds)。 resultSetHandler = (ResultSetHandler)interceptorChain.pluginAll(resultSetHandler)。 返すresultSetHandlerを。 } 公共StatementHandler newStatementHandler(エグゼキュータ、MappedStatement mappedStatement、オブジェクトparameterObject、RowBounds rowBounds、ResultHandler resultHandler、BoundSql boundSql){ StatementHandler statementHandlerは = 新しい RoutingStatementHandler(エグゼキュータ、mappedStatement、parameterObject、rowBounds、resultHandler、boundSql)を、 statementHandler = (StatementHandler)interceptorChain.pluginAll(statementHandler)。 返すstatementHandlerを。 } 公共キュータnewExecutor(トランザクショントランザクション){ 返すnewExecutor(トランザクション、defaultExecutorTypeを)。 } 公共執行newExecutor(トランザクション取引、ExecutorType executorType){ executorType = executorType == NULL?defaultExecutorType:executorType。 executorType = executorType == nullの?ExecutorType.SIMPLE:executorType。 エグゼキュータ。 もし(ExecutorType.BATCH == executorType){ キュータ = 新しいバッチ処理(このトランザクション)。 }そう であれば(ExecutorType.REUSE == executorType){ キュータ = 新しい ReuseExecutor(このトランザクション)。 } 他{ キュータ = 新しい SimpleExecutor(このトランザクション)。 } であれば(cacheEnabled){ キュータ = 新しいCachingExecutor(エグゼキュータ)。 } キュータ= (エグゼキュータ)interceptorChain.pluginAll(エグゼキュータ)。 リターンキュータ。 }
インターセプタ実装クラスを書きます
エグゼキュータインターセプター
@Intercepts({ // @Signature(タイプ= Executor.class、方法= / * org.apache.ibatis.executor.Executor中定义的方法、参数也要对应* / "更新"、引数= {MappedStatement.class、 Object.classを})、 @Signature(タイプ=執行。クラス、メソッド= "クエリ"、引数= {MappedStatement。クラス、オブジェクト。クラス、RowBounds。クラス、ResultHandler。クラス})}) パブリック クラス SelectPruningColumnPluginは実装インターセプタ{ 公開 静的 最終 ThreadLocalの<ColumnPruning> enablePruning = 新規のThreadLocal <ColumnPruning> (){ @Override 保護ColumnPruningはinitialValue() { 戻り ヌル。 } }。 ロガーロガー = LoggerFactory.getLogger(SelectPruningColumnPlugin。クラス)。 静的 int型 MAPPED_STATEMENT_INDEX = 0; // 这是对应上面的引数的序号 静的 int型 = 1 PARAMETER_INDEX 。 静的 int型 ROWBOUNDS_INDEX = 2 ; 静的 int型 RESULT_HANDLER_INDEX = 3 ; @Override パブリックオブジェクトインターセプト(呼び出しの呼び出し)がスローされたThrowableを{ 場合(enablePruning.get()!= NULL && enablePruning.get()isEnablePruning()){ オブジェクト[] queryArgsの =のinvocation.getArgs()。 MappedStatement mappedStatement = (MappedStatement)queryArgs [MAPPED_STATEMENT_INDEX]。 オブジェクトパラメータ = queryArgs [PARAMETER_INDEX]。 BoundSql boundSql = mappedStatement.getBoundSql(パラメータ)。 文字列のSQL = boundSql.getSql()。// 获取到SQL、进行调整 文字列名= mappedStatement.getId(); logger.debug( "インターセプトメソッド名は次のとおりです。" +名前+ "は、SQLは" + SQL + "パラメータがあります" +JsonUtils.toJson(パラメータ))。 文字列ExecSqlの = pruningColumn(enablePruning.get()getReserveColumns()、SQL);. Logger.debug( "改訂SQLは次のとおりです。" + ExecSqlの); // クエリへの新たな再以下のような BoundSql newBoundSql = 新新BoundSql(mappedStatement.getConfiguration()、ExecSqlの、boundSql.getParameterMappings()、boundSql.getParameterObject()); // 中の文に新しい問い合わせ MappedStatement新しいMS = copyFromMappedStatement(mappedStatement、新しい新BoundSqlSqlSource(newBoundSql) ); のため(ParameterMappingマッピング:boundSql.getParameterMappings()){ 文字列小道具 = mapping.getProperty(); IF{(boundSql.hasAdditionalParameterは()プロプ) ; newBoundSql.setAdditionalParameter(プロプ、boundSql.getAdditionalParameter()プロプ) } } queryArgs [MAPPED_STATEMENT_INDEX] = 新規MSを; // ページングクエリはPageHelperプラグがnullに設定することができないに関しため、ビジネスコンテキストが必要実行が完了した後にNULLに設定されている // enablePruning.set(ヌル); } オブジェクト結果 = invocation.proceed(); 戻り値の結果; } @Override パブリックオブジェクトプラグイン(オブジェクト・ターゲット){ }リターンPlugin.wrap(ターゲット、この)。 @Override 公共 ボイドのsetProperties(プロパティのプロパティ){ }
ResultSetHandlerインターセプター
@Intercepts({ @Signature(タイプ = ResultSetHandler。クラス、メソッド= "handleResultSets"、引数= {ステートメント。クラス})}) パブリック クラス OptMapPluginが実装インターセプタ{ @Override パブリックオブジェクトインターセプト(呼び出しの呼び出し)がスローされたThrowable { オブジェクトターゲットを = invocation.getTarget(); ステートメントSTMT =(ステートメント)invocation.getArgs()[0 ]; もし(ターゲットのinstanceof DefaultResultSetHandler){ DefaultResultSetHandler resultSetHandler =(DefaultResultSetHandler)ターゲット。 クラスCLZ = resultSetHandler.getMappedStatement()getResultMaps()(0を得る。。 )().getType を。 もし(CLZ == OptMap。クラス){ リスト <OBJECT> resultList = 新規のArrayList <オブジェクト> (); OptMap optMap = 新しいOptMap(); resultList.add(optMap)。 resultSet2OptMap(resultSetHandler.getConfiguration()、resultSetHandler、optMap、stmt.getResultSet())。 返すresultListを。 } 戻りinvocation.proceed()。 } //何インターセプト処理ロジックは、デフォルトで実行されていない場合 、戻りinvocation.proceed(); }
最後に、プラグイン構成MyBatisの-config.xmlのに次のように
<! - MyBatisの-config.xmlの注册插件- > <プラグイン> <プラグインインターセプター= "io.yidoo.mybatis.plugin.SelectPruningColumnPlugin"> <プロパティ名= "someProperty"値= "100" /> </プラグイン> </プラグイン>