読者です 読者をやめる 読者になる 読者になる

Webサービスで起業を目指すプログラマーblog

仕事で使ったプログラミング、サーバー周りで役に立つこと、Webサービス開発に必要な技術情報、モバイル情報を書いてます。わかりやすく見やすくをモットーにしています。

SpringBootとDomaを連携する

Doma SpringBoot

SpringBootとDomaの連携をGitHubにあるサンプルを参考に作ってみました。
ビルドはGradleを使っています。

環境

Java 1.7
Gradle 2.0
SpringBoot 1.1.5.RELEASE
Doma 1.37.0

ディレクトリ構成

SpringBoot標準の構成を使用します。

  • src/main/java
    • demo
      • ConfigAutowireable.java
      • DataSourceConfiguration.java
    • demo.dao
  • src/main/resources
    • application.properties
  • build.gradle

作成・編集するファイル

build.gradle

DBライブラリの依存関係を追加します。
JDBCドライバーはローカルまたはMavenリポジトリから取得し、ビルド後のjarファイルに含めるようにします。

dependencies {
    // SpringJDBC
    compile("org.springframework.boot:spring-boot-starter-jdbc")
    // Doma1.x(Java1.7まで)
    compile("org.seasar.doma:doma:1.+")
    // ローカルのOracleDriver
    compile files("C:/app/lib/jdbc/ojdbc7.jar")
}

application.properties

SpringBootのアプリケーション設定ファイルにデータベースの設定情報を記述します。

# Oracleの場合
spring.datasource.url=jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:sid
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver

ConfigAutowireable.java

DaoクラスをSpringのDIコンテナで管理するためのアノテーションを作成します。

package demo;

import org.seasar.doma.AnnotateWith;
import org.seasar.doma.Annotation;
import org.seasar.doma.AnnotationTarget;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@AnnotateWith(annotations = {
        @Annotation(target = AnnotationTarget.CLASS, type = Component.class),
        @Annotation(target = AnnotationTarget.CONSTRUCTOR, type = Autowired.class) })
public @interface ConfigAutowireable {

}

DataSourceConfiguration.java

SpringとDomaを連携するためのデータベース設定クラスを作成します。

package demo;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.seasar.doma.jdbc.Config;
import org.seasar.doma.jdbc.DomaAbstractConfig;
import org.seasar.doma.jdbc.NoCacheSqlFileRepository;
import org.seasar.doma.jdbc.SqlFileRepository;
import org.seasar.doma.jdbc.dialect.Dialect;
import org.seasar.doma.jdbc.dialect.OracleDialect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
public class DataSourceConfiguration {

	@Resource
	private Environment env;

	@Bean
	public DataSource dataSource() {

		// application.propertiesにあるDB設定キーから値を取得し設定します。
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName(env.getRequiredProperty("spring.datasource.driverClassName"));
		dataSource.setUrl(env.getRequiredProperty("spring.datasource.url"));
		dataSource.setUsername(env.getRequiredProperty("spring.datasource.username"));
		dataSource.setPassword(env.getRequiredProperty("spring.datasource.password"));

                // TransactionAwareDataSourceProxyでラッピングしないとDoma側でコネクションがおかしくなる
		return new TransactionAwareDataSourceProxy(dataSource);
	}

	@Bean
	public PlatformTransactionManager transactionManager() {
		return new DataSourceTransactionManager(dataSource());
	}

	@Bean
	public Dialect dialect() {
		// DBの方言はここで設定します。
		return new OracleDialect();
	}

	@Bean
	public SqlFileRepository sqlFileRepository() {
		return new NoCacheSqlFileRepository();
	}

	@Bean
	public Config config() {
		// Domaの設定を行います。デフォルトはDomaAbstractConfigを使用します。
		return new DomaAbstractConfig() {

			@Override
			public Dialect getDialect() {
				return dialect();
			}

			@Override
			public DataSource getDataSource() {
				return dataSource();
			}

			@Override
			public SqlFileRepository getSqlFileRepository() {
				return sqlFileRepository();
			}
		};
	}
}


# 2015/01/23追記

SpringBoot1.2以降だとプロパティファイルからの値取得にSpringで使用されている「DataSourceProperties」が使用できます。

@Autowired
private DataSourceProperties properties;

@Bean
public DataSource dataSource() {

	DriverManagerDataSource dataSource = new DriverManagerDataSource();
	dataSource.setDriverClassName(properties.getDriverClassName());
	dataSource.setUrl(properties.getUrl());
	dataSource.setUsername(properties.getUsername());
	dataSource.setPassword(properties.getPassword());

	return new TransactionAwareDataSourceProxy(dataSource);
}

TestDao.java

先ほど作成したConfigAutowireableアノテーションをDaoに設定します。

package demo.dao;

import org.seasar.doma.Dao;

import demo.ConfigAutowireable;

@Dao
@ConfigAutowireable
public interface TestDao {
}

トランザクションの設定

トランザクションを有効にするには、トランザクションを使用したいクラスまたはメソッド@Transactionalを定義します。

クラスで定義するとクラス内の全メソッドが対象、メソッドに定義するとそのメソッドのみ対象となります。

@Transactional
@Controller
public class IndexController {

    @Transactional
    @RequestMapping("/")
    public String index() {
        return "index.html";
    }
}