iBATIS3(mybatis) と Google guiceの組み合わせ、
ここに書いたもより、こちらを使うべき
http://blog.zaq.ne.jp/oboe2uran/article/458/
http://blog.zaq.ne.jp/oboe2uran/article/459/
http://blog.zaq.ne.jp/oboe2uran/article/460/
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
-------------------------------------
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 または、トランザクション インターセプタをバインド.
* コンストラクタで、configuration のXMLファイル名を指定する。
* 引数なしコンストラクタを使用した場合は、
* Configuration.xml が指定されたものとして解釈される。
*/
public class IBatisModule extends AbstractModule{
final String configXmlName;
/**
* default コンストラクタ
* @param configXmlName configurationファイル名
*/
public IBatisModule(){
this.configXmlName = "Configuration.xml";
}
/**
* コンストラクタ
* @param configXmlName configurationファイル名
*/
public IBatisModule(String configXmlName){
this.configXmlName = configXmlName;
}
/* (非 Javadoc)
* @see com.google.inject.AbstractModule#configure()
*/
@Override
protected void configure(){
Injector injector = Guice.createInjector(new AbstractModule(){
@Override
protected void configure(){
}
@SuppressWarnings("unused")
@Provides
protected SqlSessionFactory providedBatchSqlSession()
throws IOException{
return new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsReader(IBatisModule.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(IBatisModule.this.configXmlName));
}
}
---------------------------------------------------------
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* トランザクション処理を約束する.
* 対象となるメソッドと private フィールドで
* 宣言して使用するSqlSession もしくは、マッパーに付与する
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.FIELD})
public @interface Transaction{
}
---------------------------------------------------------
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.log4j.Logger;
import com.google.inject.Inject;
/**
* トランザクション インターセプター.
*/
public final class TransactionExecutor implements MethodInterceptor{
private Logger logger;
private SqlSessionFactory sqlSessionFactory;
@Inject
public TransactionExecutor(SqlSessionFactory sqlSessionFactory){
this.sqlSessionFactory = sqlSessionFactory;
this.logger = Logger.getLogger(this.getClass());
}
@Override
public Object invoke(MethodInvocation m) throws Throwable{
this.logger.trace("## TransactionExecutor START ##");
Object rtn = null;
SqlSession session = null;
try{
session = this.sqlSessionFactory.openSession(false);
this.logger.trace("## TransactionExecutor MethodInvocation#getMethod().getDeclaringClass() = "
+m.getMethod().getDeclaringClass());
Field setField = this.getAnotatedField(Transaction.class,m.getMethod().getDeclaringClass());
setField.setAccessible(true);
this.logger.debug("## @Transaction add Field Type getName = ["+setField.getType().getName()+"]");
if (setField.getType().equals(SqlSession.class)){
setField.set(m.getThis(),session);
}else{
setField.set(m.getThis(),session.getMapper(setField.getType()));
}
rtn = m.proceed();
session.commit();
this.logger.trace("## TransactionExecutor commit !");
}catch(Exception e){
if (session != null){
session.rollback();
this.logger.trace("## TransactionExecutor rollback ! ");
}
this.logger.error("#### TransactionExecutor Exception : "+e.getMessage(),e);
throw e;
}finally{
if (session != null) session.close();
this.logger.trace("## TransactionExecutor END ##");
}
return rtn;
}
private Field getAnotatedField(Class<? extends Annotation> a,Class<?> cls){
Field rtn=null;
Field fls = cls.getDeclaredFields();
for(int i=0;i < fls.length;i++){
Annotation as = fls[i].getAnnotations();
if (as != null){
for(int k=0;k < as.length;k++){
if (as[k].annotationType().equals(a)){
rtn = fls[i];
i = fls.length;
break;
}
}
}
}
return rtn;
}
}