--- title: Doma+Springの連携サンプル tags: [] categories: ["Programming", "Java", "org", "seasar", "doma"] date: 2013-08-17T00:04:54Z updated: 2013-08-17T00:04:54Z --- DomaとSpringを連携するサンプルをぐぐっても、えらく古い記事しかヒットしなかったので残しておく。 サンプルソースは[Github][1]においた。 基本はGuiceと同じで[http://doma.seasar.org/reference/config.html#DIコンテナを利用する場合の設定例][2]の通り package sample.dao; import javax.inject.Inject; import org.seasar.doma.AnnotateWith; import org.seasar.doma.Annotation; import org.seasar.doma.AnnotationTarget; import org.seasar.doma.Dao; import org.seasar.doma.Select; import org.seasar.doma.Update; import org.springframework.stereotype.Repository; import sample.entity.Employee; @Dao @AnnotateWith(annotations = { @Annotation(target = AnnotationTarget.CLASS, type = Repository.class), @Annotation(target = AnnotationTarget.CONSTRUCTOR, type = Inject.class) }) public interface EmployeeDao { @Select Employee selectById(Integer employeeId); @Update int update(Employee employee); } 生成されるクラスに`@Repository`をつけ、コンストラクタに`@Inject`をつけてBean定義した`org.seasar.doma.jdbc.Config`をautowireさせれば良い。 aptによって以下のようなコードが生成される @org.springframework.stereotype.Repository() @javax.annotation.Generated(value = { "Doma", "1.31.0" }, date = "2013-08-15T02:14:34.026+0900") public class EmployeeDaoImpl extends org.seasar.doma.internal.jdbc.dao.AbstractDao implements sample.dao.EmployeeDao { static { org.seasar.doma.internal.Artifact.validateVersion("1.31.0"); } private static final java.lang.reflect.Method __method1 = org.seasar.doma.internal.jdbc.dao.AbstractDao.__getDeclaredMethod(sample.dao.EmployeeDao.class, "update", sample.entity.Employee.class); /** * @param config the config */ @javax.inject.Inject() public EmployeeDaoImpl(org.seasar.doma.jdbc.Config config) { super(config); } // ... } Bean定義は以下。JavaConfigを使うと、Configクラスを匿名で実装できて楽。 package sample; import javax.sql.DataSource; import org.seasar.doma.jdbc.Config; import org.seasar.doma.jdbc.DomaAbstractConfig; import org.seasar.doma.jdbc.dialect.Dialect; import org.seasar.doma.jdbc.dialect.H2Dialect; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @ComponentScan(basePackages = "sample") @EnableTransactionManagement public class BeanConfig { @Bean public DataSource dataSource() { DataSource dataSource = new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .addScript("classpath:/database/schema.sql") .addScript("classpath:/database/dataload.sql").build(); return dataSource; } @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } @Bean public Dialect dialect() { return new H2Dialect(); } @Bean public Config domaConfig() { return new DomaAbstractConfig() { @Override public Dialect getDialect() { return dialect(); } @Override public DataSource getDataSource() { return new TransactionAwareDataSourceProxy(dataSource()); } }; } } daoパッケージをcomponent-scanの対象にすること。 DIコンテナと連携するとDataSourceやDialectの設定を外出し出来て良いですね。 **2014-03-24追記** Domaが`dataSource.getConnection()`を実行した際に、新規`Connection`が開かないようにDomaConfigで`DataSource`を返す際は`TransactionAwareDataSourceProxy`でラップする必要がある点に注意。 **ここまで** XMLファイルで定義する場合は以下のようにする。 トランザクション管理はDaoクラスの外のServiceクラスで行った方が良いと思う。 package sample.service; import javax.inject.Inject; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import sample.dao.EmployeeDao; import sample.entity.Employee; @Service public class EmployeeService { @Inject protected EmployeeDao employeeDao; public Employee selectById(Integer employeeId) { return employeeDao.selectById(employeeId); } @Transactional public int update(Employee employee) { return employeeDao.update(employee); } } [1]: https://github.com/making/doma-spring-example [2]: http://doma.seasar.org/reference/config.html#DIコンテナを利用する場合の設定例