iBATIS3 トランザクション(2)

ここに書いたもより、こちらを使うべき
http://blog.zaq.ne.jp/oboe2uran/article/458/

http://blog.zaq.ne.jp/oboe2uran/article/459/

http://blog.zaq.ne.jp/oboe2uran/article/460/
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

-------------------------------------

アノテーションインターセプトを書いたので、
       http://blog.zaq.ne.jp/oboe2uran/article/376/
対象クラスと Guice バインディングです。

アノテーションを以下のように付与
SqlSession 変数宣言に、@Inject ではなくて @Transaction を付与、
トランザクション処理したいメソッドに @Transaction を付与する


public class SampleUpdater implements ModelLogic{
   @Transaction private SqlSession sqlsession;

   @Transaction
   @Override
   public void doExec(){
      // 更新の処理
      this.sqlsession.update("model.update",item);
   }
}
あるいは、interface で、アノテーションにSQLをを書いて、その inteface の
インスタンスが生成されてインジェクトされるように @Transaction を付与する
以下のように、、
public class SampleUpdater implements ModelLogic{
   @Transaction private ItemMapper mapper;

   @Transaction
   @Override
   public void doExec(){
      // 更新の処理
      this.mapper.update(item);
   }
}

---------------------------------------------------------------------------
Guice バインディング定義は、AbstractModule継承クラスで用意、

import java.io.IOException;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.matcher.Matchers;
/**
 * SqlSessionFactory または、トランザクション用インターセプタをバインドさせる
 */

public class TransactionConfigure extends AbstractModule{
   final String configXmlName;
   /**
    * コンストラクタ
    * @param configXmlName configurationファイル名
    */
   public ConfigrationModule(){
      this.configXmlName = "Configuration.xml";
   }
   /**
    * コンストラクタ
    * @param configXmlName configurationファイル名
    */

   public TransactionConfigure(String configXmlName){
      this.configXmlName = configXmlName;
   }
   /*
    * @see com.google.inject.AbstractModule#configure()
    */

   @Override
   protected void configure(){
      Injector injector = Guice.createInjector(new AbstractModule(){
            @Override
            protected void configure(){
            }
            @Provides
            protected SqlSessionFactory providedBatchSqlSession() throws IOException{
               return new SqlSessionFactoryBuilder()
                      .build(Resources.getResourceAsReader(
                                        TransactionConfigure.this.configXmlName
                                                          )
                      );
            }
         }
      );

      binder().bindInterceptor(Matchers.any()
                              ,Matchers.annotatedWith(Transaction.class)
                              ,
injector.getInstance(TransactionExecutor.class)
                              );
    }
    @Provides
    protected SqlSessionFactory providedBatchSqlSession() throws IOException{
       return new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(ConfigrationModule.this.configXmlName));
    }

}

-----------------------------------------------------------
実行は、以下のように行う。

Injector injector = Guice.createInjector(new ConfigrationModule());
ModelLogic logic = injector.getInstance(SampleUpdater.class);
logic.doExec();

SqlSessionFactory をインジェクト、トランザクション用インターセプタ
両方を処理するので、トランザクション以外の単純なインジェクトのケースでも
使えるだろう