セットアップ
チュートリアルのプロジェクトをダウンロードし、環境を整えます。 JavaやEclipseのインストールがまだ完了していない場合は、先にそれらのセットアップを済ませてください。
Eclipseのインストール
バージョン3.5以上のEclipseをインストールします。 Pluggable Annotation Processing API をサポートしていれば、Eclipse以外のIDEであってもかまいませんが、 このドキュメントではEclipseを使うことを前提に説明を進めます。 Eclipseは以下のURLのサイトからダウンロードできます。
http://www.eclipse.org/downloads/
Eclipseは、バージョン6以上のJDKに含まれるJREで起動されるようにしてください。 明示的にJREを指定するには、-vm オプションを使用します。
-vm %JAVA_HOME%\bin\javaw.exe
プロジェクトのインポート
ダウンロードのページからdoma-tutorial-x.x.x.zipをダウンロードし、 Eclipseへインポートしてください。インポートの具体的な手順は次のとおりです。
- Eclipseのメニューから「File」 - 「Import」を選択します。
- 「Existing Projects to Workspace」を選択し、「Next」ボタンを押します。
- 「Select archive file」のラジオボタンをチェックし、ダウンロードしたdoma-tutorial-x.x.x.zipを選択します。
- 「Projects」の項目に表示される「doma-tutorial」のチェックボックスをチェックし、「Finish」ボタンを押します。
インポートが完了したら、doma-tutorialプロジェクトを右クリックし、コンテキストメニューから「Run As」 - 「JUnit Test」 を実行してください。 すべてのテストが成功したらセットアップが正しく完了しています。
チュートリアルの構成
チュートリアルの構成を説明します。
フォルダ構成
プロジェクトのフォルダ構成は以下の通りです。主要なものを中心に説明します。
フォルダ | 説明 |
---|---|
src | 設定クラス、Daoインタフェース、エンティティクラス、SQLファイル等のソースフォルダです。 SQLファイルは、Domaの規約に則ってMETA-INFフォルダ以下に配置されます。 また、JDBCドライバのプロバイダ構成ファイルがMETA-INF/servicesフォルダ以下にjava.sql.Driverという名前で配置されます。 |
test | Daoを利用するコードのためのソースフォルダです。 Daoを利用するコードはすべてJUnitのテストクラスとして記述されています。 |
.apt_generated | apt(Annotation Processing Tool)によって生成されたコードを格納するソースフォルダです。 Pckage Explorerビューでは、フィルタリングされるため表示されません(フィルタリングは解除可能です)。 Nivigatorビューで確認できます。 |
lib | このチュートリアルで利用するjarファイルを格納するフォルダです。 JUnit、HSQLDB、Domaのjarが格納されます。 これらのjarはすべてビルドパスに通っていなければいけません。 |
libsrc | このチュートリアルで利用するjarファイルのソースコードを格納するフォルダです。 |
データベース
このチュートリアルでは、データベースにHSQLDBを利用します。
使用するスキーマの定義は次のとおりです。 1つのシーケンスと1つのテーブルを使用します。
create sequence employee_seq as integer start with 100 increment by 1;
create table employee ( id integer not null primary key, name varchar(255) not null, age integer not null, salary integer, job_type varchar(20), hiredate timestamp, department_id integer, version integer not null, insertTimestamp timestamp, updateTimestamp timestamp );
HSQLDBはMemory-Onlyモードで起動し、テスト用のスキーマとデータは各テストの実行前に作成し、テスト終了後に破棄します。 スキーマとデータの作成と破棄は、共通のテストクラスで行っています。 Javaのコードは、test/tutorial/TutorialTestCase.javaになります。
JDBCドライバのプロバイダ構成ファイル
HSQLDBのJDBCドライバを登録するためのプロバイダ構成ファイルがsrc/META-INF/servicesに必要です。 ファイルの名称はjava.sql.Driverで、中身は次のように記述されます。
org.hsqldb.jdbcDriver
プロバイダ構成ファイルの詳細については、JAR ファイルの仕様 を参照してください。
主要なクラス
チュートリアル中の主要なクラスについて説明します。
設定クラス
設定クラスとは、Domaに関する各種設定を持つクラスです。 このチュートリアルで使用する設定クラスのソースコードは、src/tutorial/AppConfig.javaになります。
このクラスでは、HSQLDBのデータソースの作成とHSQLDBの方言の設定を行っています。 それ以外の設定については親クラスのDomaAbstractConfigのものを利用しています。 設定クラスはDaoインタフェースから利用されます。
public class AppConfig extends DomaAbstractConfig { protected static final DataSource dataSource = createDataSource(); protected static final Dialect dialect = new HsqldbDialect(); @Override public DataSource getDataSource() { return dataSource; } @Override public Dialect getDialect() { return dialect; } protected static DataSource createDataSource() { SimpleDataSource dataSource = new SimpleDataSource(); dataSource.setUrl("jdbc:hsqldb:mem:tutorial"); dataSource.setUser("sa"); return dataSource; } }
エンティティクラス
エンティティクラスとは、テーブルやSQLの結果セットにマッピングされたクラスです。 エンティティクラスは、@Entityを注釈して示します。 このチュートリアルで使用するエンティティクラスのソースコードは、src/tutorial/entity/Employee.javaになります。
Employeeクラスは、EMPLOYEEテーブルに対応します。
識別子(テーブルの主キー)には@Idを注釈します。 識別子を自動生成する場合は、さらに@GeneratedValueを注釈し、自動生成の方法を示します。 ここではEMPLOYEE_SEQシーケンスを使って採番することを示しています。
プロパティ名がマッピングするカラム名と異なる場合は@Columnのname要素を使って示します。
更新や削除時の楽観的排他制御に使用するカラムとマッピングされたプロパティには@Versionを注釈します。
@Entityのlistener要素にはEmployeeListenerクラスを指定しています。
@Entity(listener = EmployeeListener.class) public class Employee { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) @SequenceGenerator(sequence = "EMPLOYEE_SEQ") Integer id; String name; int age; Salary salary; @Column(name = "JOB_TYPE") JobType jobType; Date hiredate; @Column(name = "DEPARTMENT_ID") Integer departmentId; @Version @Column(name = "VERSION") Integer version; Timestamp insertTimestamp; Timestamp updateTimestamp; @OriginalStates Employee originalStates; ... }
エンティティリスナークラス
エンティティリスナークラスのインスタンスは、エンティティがデータベースに挿入、更新、削除されるまえに呼び出されます。 このチュートリアルで使用するエンティティリスナークラスはEmployeeListenerです。 ソースコードは、src/tutorial/entity/EmployeeListener.javaになります。
public class EmployeeListener implements EntityListener<Employee> { @Override public void preDelete(Employee employee) { } @Override public void preInsert(Employee employee) { employee.setInsertTimestamp(new Timestamp(System.currentTimeMillis())); } @Override public void preUpdate(Employee employee) { employee.setUpdateTimestamp(new Timestamp(System.currentTimeMillis())); } }
ドメインクラス
ドメインクラスは、データベースのカラムにマッピング可能なアプリケーション固有の値型です。 ドメインクラスは@Domainを注釈して示します。 このチュートリアルで使用するドメインクラスは、給料を表すSalaryクラスです。 ソースコードは、src/tutorial/domain/Salary.javaになります。
@Domain(valueType = Integer.class) public class Salary { private final Integer value; public Salary(Integer value) { this.value = value; } public Integer getValue() { return value; } public Salary add(Salary salary) { if (salary == null) { throw new NullPointerException("The salary parameter is null."); } if (this.value == null || salary.value == null) { return new Salary(null); } return new Salary(this.value + salary.value); } ... }
Daoインタフェース
Daoインタフェースとは、データベースアクセスの境界となるインタフェースです。 Daoインタフェースは@Daoを注釈して示します。 @Daoのconfig要素には設定クラスであるAppConfigクラスを指定します。 このチュートリアルで使用するDaoインタフェースのソースコードは、src/tutorial/dao/EmployeeDao.javaになります。
Daoインタフェースの実装クラスはDomaにより自動生成されます。
すべてのメソッドは、@Selectや@Updateなど問い合わせの種別を示すアノテーションが注釈されなければいけません。
@Dao(config = AppConfig.class) public interface EmployeeDao { @Select Employee selectById(Integer id); @Select List<Employee> selectByAgeRange(Integer min, Integer max); @Delegate(to = EmployeeDaoDelegate.class) int count(); @Insert int insert(Employee employee); @Update int update(Employee employee); @Delete int delete(Employee employee); @BatchInsert int[] batchInsert(List<Employee> employees); @BatchUpdate int[] batchUpdate(List<Employee> employees); @BatchDelete int[] batchDelete(List<Employee> employees); }
SQLファイル
SQLファイルは、src/META-INF/tutorial/EmployeeDaoフォルダ以下に配置されます。 フォルダの名前はDaoインタフェースと対応づけられます。
SQLファイルは、名前から拡張子を除いたものがDaoインタフェースのメソッドに一致します。 たとえば、selectById.sqlはDaoインタフェースのselectByIdメソッドに対応します。 selectById.sqlの中身は次のようなテキストです。
select * from employee where id = /* id */0