SqlSessionManager
自身がSqlSessionFactoryを達成するためにSqlSessionManager、SQLSESSION 2つのインターフェイスが、それは自分自身SQLSESSIONを構築し、Sqlsesionに宣言CURD関連するクエリメソッドを使用することができます。SqlSessionManagerコンストラクタメソッドのみ()、実際には、SqlSessionFactoryBuilder.buildのnewInstance()メソッド()メソッドはDefaultSqlsessionFactoryをインスタンスに呼び出すのnewInstanceによってインスタンス化することができ、インスタンス化できません。そして、コンストラクタを使用してインスタンス化。
内部SqlSessionManagerは、3つのプロパティsqlSessionFactory、sqlSessionProxy、localSqlSessionを維持します。知っている次のコンストラクタコードからsqlSessionProxyの建設に参加する役割SqlSessionFactoryは、ダイナミックプロキシモードのsqlSessionProxy使用はSQLSESSIONプロキシオブジェクトを作成します。CURD操作の方法に関連する将来的に、プロキシオブジェクトに委譲されます。従って、同時の安全性を確保するローカルスレッドによって維持最後プロパティlocalSqlSessionは、この機能に加えて、このプロパティは、「ナノチューブ」の概念を具現化、startManagedSession()メソッドを実行した後、対応するスレッドSQLSESSIONなりOpenSessionを介して取得()メソッドはむしろ直接ローカルスレッドから、もはや、プロキシインスタンスプロキシモードを作成、管理、。その違い以外、SqlSessionManagerもSQLSESSIONネイティブスレッドを追加複数のオブジェクトを操作するための方法を提供します。次の方法のように:
- それらはSqlSessionManager規制されているかどうかを決定するためにisManagedSessionStarted()、その本質は、オブジェクトがローカルSqlSeesionスレッドオブジェクトであるかどうかを決定することです
- getConnection()ローカル接続オブジェクトからスレッドを取得します
- ()を閉じる; SQLSESSIONスレッドが属し、SQLSESSIONをNULLに設定されている閉じ
コードがSqlSessionManagerのnewInstance()メソッド構成します
1 プライベートSqlSessionManager(SqlSessionFactory sqlSessionFactory){ 2 本 .sqlSessionFactory = sqlSessionFactory。 3 本 .sqlSessionProxy = (SQLSESSION)たとえば、Proxy.newProxyInstance( 4 。SqlSessionFactory クラス.getClassLoader()、 5 新しいクラス[] {。SQLSESSION クラス}、 6 新しいSqlSessionInterceptor())。 7 } 8 // 通过入力ストリーム进行实例化 9 パブリック 静的SqlSessionManagerのnewInstance(InputStream InputStreamは、プロパティのプロパティ){ 10 返す 新しい SqlSessionManager(新しい SqlSessionFactoryBuilderを()(InputStreamの構築。ヌル、プロパティ)); 11 } 12 // 通过SqlSessionFactory进行实例化 13 パブリック 静的SqlSessionManagerのnewInstance(SqlSessionFactory sqlSessionFactory){ 14 リターン 新しいSqlSessionManager(sqlSessionFactory)。 15 } 16 // 通过リーダー进行实例化 17 パブリック 静的SqlSessionManagerのnewInstance(リーダリーダ、文字列環境){ 18 リターン 新しい SqlSessionManager(新SqlSessionFactoryBuilder()構築(リーダー、環境、。ヌル));
我々は、インターフェイスを実装する必要がJDK動的プロキシを使用し、プロキシクラスSqlSessionInterceptorクラスをインスタンス化するのinvoke()メソッドを観察のInvocationHandlerインタフェースを実装する際のInvocationHandler()メソッド、SqlSessionManagerコンストラクタを呼び出すオーバーライドすることを知っています。ローカルSQLSESSIONスレッドからのコードの最初の行を取得しようと呼び出して、しかしstartManagedSessionは()メソッドを呼び出していない場合、あなたは、つまり、のOpenSessionにより新しいインスタンスを取得するために、各呼び出し()メソッドを、すべてのnull値を取得することはありません。
1 プライベート クラス SqlSessionInterceptor 器具のInvocationHandler {の 2 公共SqlSessionInterceptor(){ 3 // 合成Accessに防ぐ 。4 } 。5 。6 @Override 。7 パブリックオブジェクト呼び出しは、([]引数オブジェクト、プロキシ、メソッド、メソッドオブジェクト)スローのThrowableを{ 8 // ネイティブスレッドからstartManagedSessionを有効にしない限りSQLSESSIONを取得し、取得し、ローカルSQLSESSION使用SqlSessionManagerにスレッドを配置しない、例SQLSESSION場合は、ヌルである() 9。 最終 SQLSESSION SQLSESSION = SqlSessionManager。この.localSqlSession.get(); 10 IF(!SQLSESSION = NULL ){ 11 のtry { 12 リターンmethod.invoke(SQLSESSION、引数)。 13 } キャッチ(ThrowableをT){ 14 投ExceptionUtil.unwrapThrowable(T)。 15 } 16 } 他{ 17 // 通过sqlSessionFactory获取SQLSESSION 18 最終 SQLSESSION autoSqlSession = のOpenSession()。 19 試み{ 20 、最終オブジェクト結果= method.invoke(autoSqlSession、引数)。 21 autoSqlSession.commit(); 22 リターン結果; 23 } キャッチ(ThrowableをT){ 24 autoSqlSession.rollback()。 25 投ExceptionUtil.unwrapThrowable(T)。 26 } 最後に{ 27 autoSqlSession.close()。 28 } 29 } 30 } 31 }
つのインスタンスを実行します
startManagedSession使用コントラスト()SqlSessionManagerと直接法のnewInstance()は、任意の異なるテスト。まずSqlMapperを設定し、リスト方式、学生テーブル、クエリ、学生のID、名前、年齢、3つの値があります。
- SqlMapperインタフェース
1つの パッケージcom.zzz.mybatis.mapper。 2 3 インポートjava.util.Listに。 4 インポートjava.util.Map。 5 輸入org.apache.ibatis.annotations.Flush。 6 インポートorg.apache.ibatis.annotations.MapKey。 7 インポートorg.apache.ibatis.annotations.Select。 8 9 パブリック インターフェイスSqlMapper { 10 @Select( "学生からのID、名前、年齢を選択" ) 11 公衆一覧<地図<文字列、オブジェクト>> リスト(); 12 13 @Flush 14 公共 のボイド流す(); 15 16 @MapKey(値は= "ID" ) 17 @Select( "学生からのID、名前、年齢を選択" ) 18 公衆地図<文字列、地図<文字列、文字列>> listByMapkey(); 19 }
- ユニットテストクラス
1つの パッケージcom.zzz.mybatis.service。 2 3 インポートorg.apache.ibatis.session.SqlSessionManager。 4 インポートorg.junit.Test。 5つの 6 パブリック クラスSqlSessionManagerTest { 7 @Test 8 公共 ボイドSqlSessionManagerByNewInstance(){ 9 SqlSessionManagerマネージャ= SqlSessionManager.newInstance(のgetClass()getResourceAsStream( "/ MyBatisの-config.xmlの"。 ))。 10 オブジェクトrs = manager.selectOne( "com.zzz.mybatis.mapper.SqlMapper.list" )。 11 のSystem.out.println(rs.toString())。 12 } 13 14 @Test 15 公共 ボイドSqlSessionManagerByLocalThread(){ 16 SqlSessionManagerマネージャ= SqlSessionManager.newInstance(のgetClass()getResourceAsStream( "/ MyBatisの-config.xmlの"。 ))。 17 manager.startManagedSession()。 18 オブジェクトrs = manager.selectOne( "com.zzz.mybatis.mapper.SqlMapper.list" )。 19 のSystem.out.println(rs.toString())。 20の RS = manager.selectOne( "com.zzz.mybatis.mapper.SqlMapper.list" )。 21 のSystem.out.println(rs.toString())。 22 } 23 24 }
- 業績
自動コミットの設定はfalseを[com.mysql.jdbc.JDBC4Connection@5e853265] JDBC接続で ==> 準備:選択ID、名前、年齢を学生から ==> パラメータ: <== 列:ID、名前、年齢 <==行:1、zhangsan、22 <==合計:1 に設定自動コミット偽のJDBC接続の[com.mysql.jdbc.JDBC4Connection@57e1b0c] ==> 準備:選択ID、名前、年齢、学生からの ==> パラメータ: <= = 列:ID、名前、年齢 <==行:1、zhangsan、22 <==合計:1
違いと接続の両方
両方が達成するJDK動的プロキシを検索するが、雌ねじのローカルインスタンスがSQLSESSION sqlSessionProxy、SQLSESSIONインスタンスを取得するために使用するのOpenSession()メソッドを取得し使用する方法です。デバッグを使用して、非manager.startManagedSession()を使用して観察され、オブジェクトによって使用されるSQLSESSIONは、SQLSESSIONインスタンスがopenSessiom()メソッドによって取得する必要があり、localSqlSession NULLの値を取ることが分かります。
- )(非startManagedSessionを用いSQLSESSIONインスタンスを生成
startManagedSessionは()メソッドを有効にした場合、それはSQLSESSIONインスタンスにlocalSqlSessionから取得します、あなたは、ID番号のうちの2つを見ることができる二回のクエリである71は、同じインスタンスですされています。
- startManagedSessionは()SQLSESSIONインスタンスを生成し使用します