表面はSQLSESSION DO CRUDですが執行このクラス、MyBatisのは、実際には、根本的な団結コールは、このインターフェイスは、エグゼキュータです
ここではMyBatisのクエリアーキテクチャ図について投稿
エグゼキュータコンポーネント分析
MyBatisの執行は、SQLSESSION機能は、その実装に基づいているコア構成要素、動作の最も基本的な定義データベース方式の一つです。
私たちは白のデザインパターンを知られたくない、この最初の表情を分析する前に、いわば開始する前に、それは右の私が何かテンプレートモードを言うところだです
テンプレートモード:ところで、彼/テンプレートを実行するために、パブリックメソッドを定義する抽象クラス、サブクラスは、必要に応じて実装をオーバーライドますが、メソッドを呼び出すことができます抽象クラスの実行に定義されるであろう、スケルトンアルゴリズムの動作の定義は、およびサブクラスにいくつかのステップを延期、テンプレート法は、アルゴリズムの特定の実装を再定義するアルゴリズムの構造を変更しなくてもよいようなサブクラス。
テンプレートモデルは、我々はすべて、に精通していることのいくつかの例を与える必要があります:HttpClientをrestTemplate、redisTemplateに、などの標準的なスタイルのテンプレートパターンです。
テンプレートモードのアプリケーションのシナリオ:
プロセスは一連のステップで構成されて遭遇は、テンプレートパターンの使用を検討する必要上、ビューの高レベルの点から処理が同じである構成実行されるが、いくつかの手順が異なっていてもよく達成するために、この時間を必要とします。
次に、我々はこのexecutorそれについて話します。
テンプレートパターンの使用に、BaseExecutorは、抽象化のテンプレートモードで、彼は物事とキャッシュ管理を管理する機能を提供する方法エグゼキュータ・インターフェースのほとんどを実現し、他の抽象メソッドは、AサブクラスdoUpate、doQueryなどとして実装する必要がある場合方法;
そして、完全な実装プロセスそれMyBatisのについて話します
SQLSESSIONの実行
クエリ内の結束にエグゼキュータ・リターン
バーコードステッカーexecutor.query
1つの @Override 2 公共 <E>リストの<E>クエリ(MappedStatementミリ秒、オブジェクトパラメータ、RowBoundsのrowBounds、ResultHandler resultHandler)がスローするSQLException { 3 BoundSql boundSql = ms.getBoundSql(パラメータ)。 4 CacheKeyキー= createCacheKey(MS、パラメータ、rowBounds、boundSql)。 5 リターンクエリ(MS、パラメータ、rowBounds、resultHandler、キー、boundSql)。 6 }
初期化がMappedStatementに格納されているためMappedStatementから取得したSQL文を取得している起動し、くらいそこに話をされていない、あなたは私が前に書いたものを見ることができます知ってほしい、あなたは百度を所有することができます
情報の既存の4種類を通じ、私は特定の分析キャッシュ基盤サポートモジュールを見ることができる前に、キャッシュCacheKeyとしての作成を開始します。
1 @SuppressWarnings( "をチェック" ) 2 @Override 3 パブリック <E>リストの<E>クエリ(MappedStatementミリ秒、オブジェクトパラメータ、RowBounds rowBounds、ResultHandler resultHandler、CacheKeyキー、BoundSql boundSql)がスロー{SQLExceptionが 4 ErrorContext.instance()。リソース(ms.getResource())活性( "クエリーの実行"。).object(ms.getId())。 5 あれば(閉){ 6 投 新しい ExecutorException( "エグゼキュータが閉じられました。" )。 7 } 8 であれば(queryStack == 0 && ms.isFlushCacheRequired()){ 9 clearLocalCache(); 10 } 11 リスト<E> リスト。 12 試み{ 13 queryStack ++ 。 14 リスト= resultHandler == nullの?(一覧<E>)localCache.getObject(キー):ヌル; 15 であれば(!リスト= NULL ){ 16 handleLocallyCachedOutputParameters(MS、キー、パラメータ、boundSql)。 17 } 他{ 18 リスト= queryFromDatabase(MS、パラメータ、rowBounds、resultHandler、キー、boundSql)。 19 } 20 } 最後に{ 21で queryStack--は、 22である } 23が IF(queryStack == 0 ){ 24 用(DeferredLoad deferredLoad:deferredLoads)プロセスデータの{//遅延ローディング 25 deferredLoad.load(); 26である } 27 // 号601# 28 deferredLoads.clear(); 29 IF(configuration.getLocalCacheScope()== LocalCacheScope.STATEMENT){//キャッシュSQL文の現在の構成、直ちにクエリ完全に空キャッシュ場合 30 // 問題#482 31は clearLocalCache(); 32 } 33 } 34 リターンリスト。 35 }
非ネストされたクエリとflushCacheには、キャッシュを空にし、真の構成されました
条件によると、単純な分析CacheKeyクエリキャッシュあれば、誰かがここで聞いてきます、MyBatisのは二次キャッシュはそれではありませんチェックしますと?ではない心配を行い、MyBatisの二次キャッシュがBaseExecutorにその後、ここに書かれていませんキャッシュへの確かに直接アクセス
、キャッシュに置か:キャッシュヒットが返された場合、データベースからデータをロードをヒットしない場合は、(| |リユースバッチシンプルな3つの方法があります)。
BaseExecutor画定するようクエリ骨格のみのデータベース操作についてあったAを達成するためにサブクラスによって変更または上書きすることができ
3つの実装クラスの解釈キュータ
SimpleExecutor:デフォルトの設定、アクセスに使用するのprepareStatementオブジェクトデータベースは、各訪問は新しいのprepareStatementオブジェクトを作成する必要があります。
ReuseExecutor:キャッシュ内の文オブジェクトを再利用しますが、プリコンパイルのprepareStatementオブジェクトのAccessデータベース、Accessを使用して、
バッチ処理:バッチは、複数のSQL文を実行達成する能力。
まずSimpleExecutor来ます
1 @Override 2 公共 <E>リストの<E> doQuery(MappedStatement MS、パラメータオブジェクト、RowBoundsのRowBounds、ResultHandler resultHandler、BoundSql boundSql)がスローするSQLException { 3 ステートメントSTMT = NULLを、 4 トライ{
//取得グローバル構成 5。 設定設定= ms.getConfiguration();
//はStatementHandlerオブジェクト作成 6。 StatementHandlerハンドラ= configuration.newStatementHandler(warpper、MS、パラメータ、RowBounds、resultHandler、boundSql);
// StatementHandlerオブジェクトがSTMTを作成し、のprepareStatementのプレースホルダで処理される 。7 STMT =prepareStatement(ハンドラ、ms.getStatementLogは());
// ResultSetHandler statementHandlerオブジェクト呼び出すことにより、指定されたオブジェクトの変換結果セットを返す 8。 復帰ハンドラ<E> クエリ(STMT、resultHandler); 9 } 最後に{ 10 closeStatement(STMT)。 11 } 12 }
1つの プライベートステートメントのprepareStatement(StatementHandlerハンドラ、ログstatementLog)がスローするSQLException { 2 ステートメントSTMTと、
//在这里获取的Connetion 3 接続の接続= のgetConnection(statementLog)。 4 STMT = handler.prepare(接続、transaction.getTimeout())。 5 handler.parameterize(STMT)。 6 リターンのstmt; 7 }
。1つの 保護接続のgetConnection(ログstatementLog)がスローするSQLException { 2 接続の接続= transaction.getConnectionを(); 3 IF (statementLog.isDebugEnabled()){
//ここに返さ拡張動的プロキシ呼接続である
//学ぶログ前のパラメータ文を印刷する記事にMyBatisのソースモジュールは、研究の最初の日(ロギングモジュール)上のように参照
、印刷エンハンスメント型への呼び出しチェーンが戻るに使用される埋め込みコードを//ここでエレガントな方法の後 。4 リターンConnectionLogger.newInstanceを(接続、statementLog、queryStack); 5 } 他{ 6。 リターン接続; 7 } 。8 }
> PrepareStatementLogger - - > ResultSetLogger ConnectionLoggerを印刷するためのコールログチェーンについて簡単に説明
たとえばStatementHandler後、実際には、それはテンプレートパターンである、抽象クラスはスケルトン、三つのサブクラスの実装を構築し、我々はまた見に行くことができ、困難は何もありません
その後ReuseExecutor
1つの @Override 2 公共 <E>リストの<E> doQuery(MappedStatementミリ秒、オブジェクトパラメータ、RowBounds rowBounds、ResultHandler resultHandler、BoundSql boundSql)がスローSQLExceptionが{ 3 コンフィギュレーション設定= ms.getConfiguration()。 4 StatementHandlerハンドラ= configuration.newStatementHandler(ラッパー、MS、パラメータ、rowBounds、resultHandler、boundSql)。 5 ステートメントSTMT = のprepareStatement(ハンドラ、ms.getStatementLog())。 6 リターン・ハンドラ<E>。クエリ(stmtは、resultHandler)。 7 }
見てのように、本当に、何も異なる、アプローチのprepareStatement内の特定の違い、それではありません
1 プライベートステートメントのprepareStatement(StatementHandlerハンドラ、ログstatementLog)がスローするSQLException { 2 ステートメントSTMTを、 3 BoundSql boundSql = handler.getBoundSql(); 4 列SQL = boundSql.getSql(); SQL文を取得// 5 IF (hasStatementFor(SQL) ){// SQL文をチェックし、対応するキャッシュするかどうかステートメント 6。 STMT = getStatement(SQL); //取得キャッシュステートメント 7。 applyTransactionTimeout(STMT); //新しいタイムアウトを設定する 。8 } 他{//全くバッファしませんステートメントを作成する文の作成とSimpleExecutor文のプロセスと同様の 9 接続の接続=getConnection(statementLog); 10 STMT = handler.prepare(接続、transaction.getTimeout()); 11 putStatement(SQL、STMT); //キャッシュに入れ 12は }
プレースホルダ使用//のprepareStatementプロセス 13は、 (handler.parameterize STMT); 14 戻りSTMT; 15 }
キャッシュを知っている必要はありません間違いなく地図です
1 民間 最終地図<文字列、声明> statementMap = 新しい HashMapの<>();
はい、これはよくして面白い何かを言っていない、キャッシュ地図41行でそれに迂回です......
二次キャッシュが開いていない場合は徒歩で、最初の二次キャッシュキャッシュを行くように、二次キャッシュがオンになっている場合、それは希望の包装のCachingExecutor層であるCachingExecutor BaseExecutorにデコレータをパッケージ化することです、その後、二次キャッシュ、その後、キャッシュに直接移動
1 @Override 2 公共 <E>リストの<E> クエリ(MappedStatementミリ秒、オブジェクトparameterObject、RowBounds rowBounds、ResultHandler resultHandler、CacheKeyキー、BoundSql boundSql) 3 スローのSQLException {
//从MapperStatement中获取二级缓存 4 キャッシュキャッシュ= ミリ.getCache()。 5 もし(!キャッシュ= NULL ){ 6 flushCacheIfRequired(MS)。 7 場合(ms.isUseCache()&& resultHandler == NULL ){ 8 ensureNoOutParams(MS、boundSql)。 9 @SuppressWarnings( "未チェック" ) 10 一覧<E>リスト=(一覧<E> )tcm.getObject(キャッシュ、キー)。 11 であれば(リスト== NULL ){
//二级缓存为空、才会调用BaseExecutor.query 12 リスト=デリゲート<E> クエリ(MS、parameterObject、rowBounds、resultHandler、キー、boundSql)。 13 tcm.putObject(キャッシュ、キー、リスト)。// 問題#578と#116 14 } 15 リターンリスト。 16 } 17 } 18 リターンデリゲート<E> クエリ(MS、parameterObject、rowBounds、resultHandler、キー、boundSql)。 19 }
デコレータは、キャッシュモジュールで言った前に、百度してください理解し、または私はキャッシュモジュールの前に書いたものを見てはいけません
3つのアクチュエータのキュータ
方法によるSimpleExecutor doQueryの解釈は、エグゼキュータの司令官、彼の仕事のスケジューラ3つのアクチュエータを見つけました。
StatementHandlerは:彼の役割は、ステートメントのprepareStatementデータベースを使用するか、甲斐が役割を接続し、操作を実行することです。
ParameterHandler:対応するパラメータ名と、このオブジェクトのパラメータの関連する属性を記録素子BoundSql.parameterMappingsコレクションにプリコンパイルされた設定パラメータのSQL文で、SQL文のプレースホルダの対応、?
ResultSetHandler:結果を返すユーザにより指定されたタイプのインスタンスにカプセル化データベース(ResultSetの)に戻す設定します。
ここでSQLSESSION私は仕事エグゼキュータのは好きではないと言う私はStatementHandlerそれをしないだろうか、あなたは、あなたは何をしますか
前のように - >>プロジェクトマネージャ - デベロッパー>>
ここで3つのアクチュエータは、それぞれの治療の異なる時期に対応します
StatementHandler - > parameterHandler - > resultSetHandler
!申し訳ありませんが、書き込みに明日、少し遅れて、ここでのポイントの残りの部分を完了するために、今日
著者:大西洋ダンス
時間:2020 \ 03 \ 22
MyBatisの:に関するコンテンツ
ネットワークからのこの記事で、唯一の技術の共有は、一切の責任を受け入れてはなりません