2014年7月1日火曜日

Doma を使って Java の DAO を楽にする。

○javaアプリケーション の DAO に何を使うか? Doma が良さそう。


How to use doma ? ということで、


JavaのDaoフレームワークである、Doma(ここでは Doma1 を)を導入します。
Domaは2waysql方式で、発行したSQLがわかりやすく、ローカルトランザクションをサポートしています。

大きな連続した命令を行う必要がないアプリケーションであれば、十分な機能を有しています。

また、他のライブラリへの依存が無いこともよいです。

Doma -----------

データ型:http://doma.seasar.org/reference/basic.html
エンティティ定義:http://doma.seasar.org/reference/entity.html
トランザクション:http://doma.seasar.org/reference/transaction.html
アノテーション:http://doma.seasar.org/reference/apt.html
Daoインターフェース:http://doma.seasar.org/reference/dao.html

■DB生成

MySQLにテーブルを構築します。
今回は、テスト用に1つテーブルを作成しました。

ex)
○テーブル
use beta_doma_table;
CREATE TABLE `beta_doma_table`.`beta_doma` (
  `beta_doma_id` INT NOT NULL AUTO_INCREMENT,
  `beta_doma_message` VARCHAR(255) NULL,
  `beta_doma_number` INT NULL,
  `beta_doma_created_at` TIMESTAMP NULL,
  `beta_doma_updated_at` TIMESTAMP NULL,
  `beta_doma_deleted_flag` TINYINT NULL DEFAULT 0,
  `beta_doma_deleted_at` TIME NULL DEFAULT NULL,
  PRIMARY KEY (`beta_doma_id`),
  UNIQUE INDEX `beta_doma_id_UNIQUE` (`beta_doma_id` ASC))
ENGINE = InnoDB
COMMENT = 'test for doma table';

○テスト用データ
use beta_doma_table;
insert into beta_doma (beta_doma_message, beta_doma_number, beta_doma_created_at, beta_doma_updated_at) values('test1こんにちは', 101, now(), now());
insert into beta_doma (beta_doma_message, beta_doma_number, beta_doma_created_at, beta_doma_updated_at) values('test2ありがとう', 102, now(), now());
insert into beta_doma (beta_doma_message, beta_doma_number, beta_doma_created_at, beta_doma_updated_at) values('test3すばらしい!', 103, now(), now());
insert into beta_doma (beta_doma_message, beta_doma_number, beta_doma_created_at, beta_doma_updated_at) values('test4確かに', 104, now(), now());
insert into beta_doma (beta_doma_message, beta_doma_number, beta_doma_created_at, beta_doma_updated_at) values('test5緩やかに', 105, now(), now());
insert into beta_doma (beta_doma_message, beta_doma_number, beta_doma_created_at, beta_doma_updated_at) values('test6そうですね', 106, now(), now());
insert into beta_doma (beta_doma_message, beta_doma_number, beta_doma_created_at, beta_doma_updated_at) values('test7反対です', 107, now(), now());
insert into beta_doma (beta_doma_message, beta_doma_number, beta_doma_created_at, beta_doma_updated_at) values('test8。。。888888', 108, now(), now());

■データソースの生成
以下の用にDBへのアクセス情報を保持しておきます。
MySQLの方言も吸収します。

public class AppConfig extends DomaAbstractConfig {
protected static final LocalTransactionalDataSource dataSource = createDataSource();
protected static final Dialect dialect = new MysqlDialect();
public DataSource getDataSource() {
return dataSource;
}
public Dialect getDialect() {
return dialect;
}
protected static LocalTransactionalDataSource createDataSource() {
SimpleDataSource dataSource = new SimpleDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/beta_doma_table?useUnicode=true&characterEncoding=utf8");
dataSource.setUser("****");
dataSource.setPassword("****");
return new LocalTransactionalDataSource(dataSource);
}
public static LocalTransaction getLocalTransaction() {
return dataSource.getLocalTransaction(defaultJdbcLogger);
}
}
view raw AppConfig.java hosted with ❤ by GitHub
■Entityの生成
テーブルに対応したEntityを生成します。
自動生成するツール Doma Gen もあるようなので、後日試します。

@Entity(naming = NamingType.SNAKE_LOWER_CASE)
public class BetaDoma {
@Id
@Column(name = "beta_doma_id")
public Integer id;
@Column(name = "beta_doma_message")
public String message;
@Column(name = "beta_doma_number")
public Integer number;
@Column(name = "beta_doma_created_at")
public Timestamp createdAt;
@Column(name = "beta_doma_updated_at")
public Timestamp updatedAt;
@Column(name = "beta_doma_deleted_flag")
public Integer deleted_flag;
@Column(name = "beta_doma_deleted_at")
public Timestamp deletedAt;
}
view raw BetaDoma.java hosted with ❤ by GitHub

■Entityに対するDaoを生成
Entityに対する操作をDaoに定義します。
引数をカラム名と等しくする必要があります。

@Dao(config = AppConfig.class)
public interface BetaDomaTableDao {
/**
*
* @param beta_doma_id 必要事項:カラム名と一致
* @return
*/
@Select
BetaDoma selectById(Integer beta_doma_id);
@Update
int update(BetaDoma betaDomaTable);
}

■コンパイル時のアノテーションプロセス
プロジェクトプロパティの[JavaCompiler]-[Annotation Processing]-[Enable project specific settings]をonにします。

Generated source directoryには「.apt_generated」とします。

[Factory Path]には、domaのライブラリ(doma-1.XX.X.jar)を指定します。

■プロジェクトビルド
antでdomaをビルドします。
destにはビルド先を指定します。Daoインターフェースの実装クラス(Impl)がDomaによって生成されます。
targetには、jarが出来ます。

<project name="doma-tutorial" default="jar" basedir=".">
<property name="dest" value="src/target/build"/>
<property name="apt_generated" value="src/target/apt_generated"/>
<property name="src" value="src"/>
<property name="resources" value="src"/>
<path id="classpath">
<fileset dir="libs" includes="*.jar"/>
</path>
<target name="jar" depends="clean,copy,compile">
<jar jarfile="target/doma-own-test.jar" basedir="${dest}" />
</target>
<target name="clean">
<delete dir="target" failonerror="false"/>
<mkdir dir="target"/>
<mkdir dir="${dest}"/>
<mkdir dir="${apt_generated}"/>
</target>
<target name="compile">
<javac fork="yes" compiler="javac1.7" debug="on" encoding="UTF-8"
classpathref="classpath" srcdir="${src}" destdir="${dest}">
<compilerarg line="-s ${apt_generated}" />
</javac>
</target>
<target name="copy">
<copy todir="${dest}" filtering="true">
<fileset dir="${resources}">
<include name="META-INF/**" />
</fileset>
</copy>
</target>
</project>
view raw build.xml hosted with ❤ by GitHub


■生成jarをビルドパスに追加
targetに生成したjarをビルドパスに追加します。
JavaのアプリケーションからdomaのDAO機能を使うことが出来ます。


■テスト用コード
以下の用にEntityを取得し、更新が可能です。

public class Main {
public static void main(String[] args){
LocalTransaction tx = AppConfig.getLocalTransaction();
try{
tx.begin();
BetaDomaTableDao dao = new BetaDomaTableDaoImpl();
BetaDoma betaDomaTable = dao.selectById(2);
betaDomaTable.message = "renew message 更新したよ!";
betaDomaTable.number = 10000;
dao.update(betaDomaTable);
tx.commit();
}finally{
// トランザクション
tx.rollback();
}
}
}
view raw Main.java hosted with ❤ by GitHub
以上で、Domaの基本的な操作は完了です。
大きなデータベースの場合、Entityを手動で書くことが難しくなります。
そのため、Doma gen が力を発揮するのでしょう。

0 件のコメント:

コメントを投稿