はじめに:
我々はMyBatisのを使用する場合、我々は、カスタムプラグインの変化に、我々はプラグインの実装の原則を理解しなければならない必要がある場合、必ず、その上、このようなPageHelperなどのプラグイン、各種の(ページネーションプラグイン)とを使用します。
アウトライン
MyBatisのプラグイン、またインターセプタ、よりダイナミックプロキシプラグイン組織(インターセプター)で採択された責任のパターンのMyBatisのチェーンとして知られているが、あなたはこれらのプラグインを通じてデフォルトの動作MyBatisのを変更することができます。MyBatisのマッピングプロセスを使用すると、インターセプト呼び出しにポイントのステートメントの実行を持つことができます。デフォルトでは、MyBatisのは、インターセプトメソッド呼び出しへのプラグインの使用を可能にします。
- エグゼキュータ(更新、照会、flushStatements、コミット、ロールバック、getTransaction、近い、閉じられ)メソッド遮断アクチュエータと
- ParameterHandler(getParameterObject、setParametersを使用)インターセプト処理パラメータ。
- 結果セットの処理をインターセプトResultSetHandler(handleResultSets、handleOutputParameters)。
- SQL文法構造を処理切片にStatementHandler(パラメータ化、バッチ、更新、照会、準備)。
4つのインターフェイスをMyBatisの
図MyBatisの実行上部フレーム全体。MyBatisのプラグインは、MyBatisの最初の会議の全体的な動作に組み込むことができる4つのオブジェクトをインターセプト。目に見えるプラグMyBatisのは非常に強力です。
- エグゼキュータはMyBatisの内部操作呼び出しStatementHandlerデータベースの原因であるアクチュエータ、およびマッピングResultSetHandlerによって自動的に設定された結果であり、さらに、彼はまた、二次キャッシュの動作を取り上げました。ここからわかるように、我々は2つのキャッシュが、カスタムプラグインを介して達成することができるレベルです。
- StatementHandler MyBatisのオブジェクトデータベースと直接SQLスクリプトを実行します。また、それはまた、MyBatisののキャッシュを実装しています。ここでは、(無効、など)のキャッシュの動作を実現するプラグインを使用することができます。
- ParameterHandler MyBatisのは、パラメータ設定のSQLオブジェクトに実装されています。プラグインは、私たちのパラメータのSQLのデフォルト設定を変更することができます。
- ResultSetHandler MyBatisのはPOJO ResultSetインタフェースオブジェクトの集合にマッピングされます。我々は、MyBatisの自動マッピングが変更される結果、プラグインのセットを定義することができます。
インターセプターは、(4つのインターフェイス)を傍受できる理由
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
return parameterHandler;
}
public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql) {
ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);
resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
return resultSetHandler;
}
public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
return statementHandler;
}
public Executor newExecutor(Transaction transaction, ExecutorType executorType, boolean autoCommit) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
executor = new SimpleExecutor(this, transaction);
}
if (cacheEnabled) {
executor = new CachingExecutor(executor, autoCommit);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
これらの4つの方法は、対応するオブジェクトをインスタンス化した後、interceptorChain pluginAllは、その後、我々はpluginAllに何をしたかの下に見えるメソッドを呼び出します
public class InterceptorChain {
private final List<Interceptor> interceptors = new ArrayList<Interceptor>();
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
public void addInterceptor(Interceptor interceptor) {
interceptors.add(interceptor);
}
public List<Interceptor> getInterceptors() {
return Collections.unmodifiableList(interceptors);
}
}
このpluginAllすべてのインターセプタをループであり、そして我々は層によって、プラグインの順序、層を接続する方法を実行するように、我々は、元のオブジェクト(エグゼキュータ/ ParameterHandler / ResultSetHander / StatementHandler)プロキシオブジェクトを返します。この方法は、実際にはプロキシオブジェクトのインスタンス4インタフェースオブジェクトのプロキシオブジェクトに応じて呼び出されたときの方法は、我々は4つのインタフェースオブジェクトを呼び出すときに呼び出します。
インターセプタインターセプタ
プラグインの実装のMyBatisのがインターセプタを実装するために、我々はこのインタフェースで定義されたメソッドを見てください。
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
インターフェースは、3つのメソッドを宣言します。
- インタフェースオブジェクトパラメータ:setPropertiesメソッドは、プラグ相関MyBatisの設定のカスタム属性、すなわち内に配置されたとき
- プラグインメソッドは、我々がターゲットオブジェクト自体に戻ることができたことで、対象物を、カプセル化するために使用され、それはまた、プロキシを返すことができるプラグイン、あなたがインターセプトするかどうかを決定し、その後、どのような観客の返すことを決めることができ、公式の例を提供します:リターンPlugin.wrap(ターゲット、この);
- インターセプト法は、インターセプト法であるときに実行されます
公式推奨プラグインの開発モード
@Intercepts({@Signature(type = Executor.class, method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class TestInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget(); //被代理对象
Method method = invocation.getMethod(); //代理方法
Object[] args = invocation.getArgs(); //方法参数
// do something ...... 方法拦截前执行代码块
Object result = invocation.proceed();
// do something .......方法拦截后执行代码块
return result;
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
}
書くシンプルなプラグインMyBatisの
注:MyBatisのデフォルトのクラスは、インターセプタのインターフェースを実装していない、開発者はインターセプタ彼らのニーズに合わせて実装することができます。
以下の公式ウェブサイトは、インターセプタインスタンスをMyBatisの:
@Intercepts({@Signature(type= Executor.class, method = "update", args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
return invocation.proceed();
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
}
}
グローバルXML設定:
<plugins>
<plugin interceptor="org.format.mybatis.cache.interceptor.ExamplePlugin"></plugin>
</plugins>
インターセプタインターセプタ更新方法キュータインタフェース(実際には、SQLSESSIONの追加、削除、変更操作である)、更新方法のすべての実行エグゼキュータはインターセプターを傍受するであろう。