MyBatisのワークフロー:
(1)XMLファイルからSqlSessionFactoryBuilderまたはJava SqlSessionFactory方式の構成の一例を構成します。
(2)SqlSessionFactory生成SQLSESSION。
(3)Mapperプロキシオブジェクトを取得SQLSESSION(マッパープロキシによってJDK動的プロキシを生成し、プロキシクラスは、我々はマッパーを書き込むインタフェースを実装します)。
(4)MapperProxyによる方法Maper呼び出しを対応します。
1.ビルドプロセスSqlSessionFactory
メインの建物は、2つのステップに分かれています。
- XMLConfigBuilderベースマッパー構成XMLファイルやXMLファイルを含む、XMLファイル、読み出した設定パラメータを解析して構成。
- SqlSessionFactoryはConfigurationオブジェクトを使用して作成し、SqlSessionFactoryには、デフォルトの実装クラスDefaultSqlSessionFactoryを提供するインタフェースです。
2. MappedStatement
SQL、SQLのID、キャッシュ構成情報、このresultMap、のParameterType、resultTypeと構成、およびその他の重要なコンテンツを含む、(更新|挿入| |削除を選択)マッパーを保持しているノード。
3. SqlSource
これは、主な役割は、パラメータや組立SQLの他のルールに基づいており、属性MappedStatementです。
4. BoundSql
SQLとパラメータについては、主にプラグインで、それが現在実行中のSQLおよびパラメーターならびに規則を介して取得し、BoundSqlクラスオブジェクトに反映され、特定の要件を満たすために適切な変更を行います。
parameterObject、parameterMappingsとSQL:BoundSqlは、3つの主要な属性を提供しています。
自身parameterObjectパラメータとして、あなたは単純なオブジェクトを渡すことができ、POJO、地図や@Param注釈パラメータ:
- 単純なオブジェクト(整数、浮動小数点、文字列、など)を通過する、INTは整数に変換など、対応するパラメータの型に変換されます。
- あなたがPOJOまたはマップを渡すと、paramterObjectは変わらず、着信またはPOJO地図です。
- P3 ... "のparam1":P1、 "2":P2、 "3" あなたは、複数のパラメータを渡すと、何@Paramアノテーションは、parameterObjectは形で、このような地図<文字列、オブジェクト>オブジェクトは、{ "1" ではありません:P1、 "PARAM2" P2、 "param3"、P3は、...}、{1つの参照最初のパラメータにPARAM1の調製}または{は##}で使用することができます。
- 伝送パラメータが複数の場合、そこ@Param注釈、注釈と類似していない、指定された名前@Paramキーのシリアル番号の交換を除きます。
parameterMappingsは、その要素は名前、表現、JavaTypeが、jdbcType、typeHandlerやその他の情報を含むSQLパラメータ参照を、描写するオブジェクトをParameterMappingされ、一覧です。
SQLは、マッパーSQLの内側に書かれています。
実行中のプロセスのSQLSESSION
1.動的プロキシマッパー
マッパーマッピングは発信者アクセスのためのプロキシオブジェクトを返すためにJDK動的プロキシを使用し、動的プロキシを介して達成されます。
まず見た目のInvocationHandlerインタフェースの実装クラス、それはプロキシメソッドの実装の鍵である、あなたが見ることができる、マッパーは、executeメソッドを呼び出し、MapperMethodオブジェクトを生成しますインターフェースです。
パブリック クラス MapperProxyは<T> 実装のInvocationHandler、直列化を{ ..... @Override パブリックオブジェクトを呼び出し(オブジェクトのプロキシは、メソッドの方法は、[]引数オブジェクト)スローのThrowableが{ 試みる{ 場合(オブジェクト。クラス(.equals method.getDeclaringClass( ))){ 戻り method.invoke(本)、引数を、 } 他の 場合(isDefaultMethod(メソッド)){ 戻りinvokeDefaultMethod(プロキシ、メソッド、引数)を、 } } キャッチ(ThrowableをT){ スローExceptionUtil.unwrapThrowable(T)。 } 最終 MapperMethod mapperMethod = cachedMapperMethod(方法) 返すmapperMethod.execute(SQLSESSION、引数を)。 } }
異なる処理操作SQLに応じて、コマンドモードを使用しMapperMethod。
パブリック クラスMapperMethod { パブリックオブジェクト実行(SQLSESSION SQLSESSION、オブジェクト[]引数){ オブジェクト結果、 スイッチ(command.getType()){ ケースINSERT:{ オブジェクトPARAM = method.convertArgsToSqlCommandParam(引数)。 結果 = rowCountResult(sqlSession.insert(command.getName()、PARAM))。 破ります; } ケースUPDATE:{ オブジェクトPARAM = method.convertArgsToSqlCommandParam(引数)。 結果 = rowCountResult(sqlSession.update(command.getName()、PARAM))。 ブレーク; ... } } }
最後に、プロキシクラスの生成方法を見て、それが作成するために、JDKの動的プロキシプロキシを使用することです。
パブリック クラス MapperProxyFactory <T> { パブリックTのnewInstance(SQLSESSION SQLSESSION){ 最終 MapperProxy <T> mapperProxy = 新しい MapperProxy <T> (SQLSESSION、mapperInterface、methodCache)。 返すのnewInstance(mapperProxyを)。 } @SuppressWarningsは( "未チェック" ) 保護された TのnewInstance(MapperProxy <T> mapperProxy){ リターン(T)たとえば、Proxy.newProxyInstance(mapperInterface.getClassLoader()、新しいクラス[] {} mapperInterface、mapperProxy)。 } }
あなたが実際には、そのメソッドの1つを呼び出すときに要約プロシージャコールマッパーの下では、マッパーオブジェクトは、プロキシオブジェクトを返し、対応するインタフェースへのフルパスがMapperProxy#のinvokeメソッドの呼び出し、およびXMLファイルマッパーの名前空間です方法の完全なパスおよび名前によれば、SQLに移動し、最大に結合することができ、最終的に方法SQLSESSIONインタフェースを使用してクエリを実行することを可能にします。
2. SQLSESSION下の四つのオブジェクト
マッパーは動的プロキシオブジェクトである、簡単な判断を通じてSQLSESSIONは、削除、更新、挿入、他の方法を選択し入力されたexecuteメソッドMapperMethod、に進みます。マッパー実行処理データベース操作が達成され、結果は、執行、StatementHandler、ParameterHandlerとResultHandlerによって返されます。
- エグゼキュータ:SQLエグゼキュータ、その他の三つの統一されたオブジェクトによっては、対応を実行します。
- StatementHandler:使用ステートメントは、データベース操作を実行します。
- ParameterHandler:処理パラメータのためのSQL。
- ResultHandler:カプセル化プロセスは、最終的なデータセットを返します。
MyBatisの持つ3個のアクチュエータがあります。
- SIMPLE:単純なアクチュエータ、デフォルトのアクチュエータ。
- REUSE:実行する再利用は、ステートメントを準備し;
- BATCH:文とバッチ更新、バッチ用の専用のアクチュエータを再利用の実現。
実装プロセスを説明するために例をSimpleExecutorします。
パブリック クラス SimpleExecutorは延びBaseExecutor { / ** *执行查询操作 * / パブリック <E>リストの<E> doQuery(MappedStatementミリ秒、オブジェクトパラメータ、RowBounds rowBounds、ResultHandler resultHandler、BoundSql boundSql)がスローするSQLException { ステートメントSTMT = ヌル。 試す{ 構成設定 = ms.getConfiguration()。 StatementHandlerハンドラ = configuration.newStatementHandler(この、MS、パラメータ、rowBounds、resultHandler、boundSql)。 stmtは =prepareStatement(ハンドラ、ms.getStatementLog()); リターン・ハンドラ<E>。クエリ(stmtは、resultHandler)。 } 最後に{ closeStatement(STMT)。 } } / ** *初始化StatementHandler * / プライベートステートメントのprepareStatement(StatementHandlerハンドラ、ログstatementLog)がスローするSQLException { ステートメントSTMTと、 接続の接続 = のgetConnection(statementLog)。 STMT = handler.prepare(接続)。 handler.parameterize(STMT)。 リターンのstmt; } / ** *执行查询 * / @Override 公共 <E>リスト<E>クエリ(声明、ResultHandler resultHandler)がスローするSQLException { 文字列のSQL = boundSql.getSqlを(); Statement.execute(SQL)。 返す resultSetHandlerを<E>。handleResultSets(声明)。 } }
あなたは、最後のセッションがStatementHandlerに委託されます見ることができます処理され、それはそれは本当にRoutingStatementHandlerオブジェクトを作成して、インターフェイスですが、それはアダプタモードによって行わ対応StatementHandlerを見つけることである真のサービスオブジェクト、ではありません。エグゼキュータとしてMyBatisの、StatementHandlerとの三種類に分け:SimpleStatementHandler、PreparedStatementHandler、CallableStatementHandler。
エグゼキュータは、最初の準備の方法StatementHandlerプリコンパイルされたSQL文を呼び出し、いくつかの基本的な動作パラメータを設定します。次いでParameterHandlerを有効にする()メソッドをパラメータ化呼び出しは、プリコンパイルを完了するためにパラメータを設定し、クエリの実装に伴い、パッケージResultHandler結果と呼び出し元に返さ。