はじめに
DomaはJava 8以上で動作するデータベースアクセスフレームワークです。JDBCドライバが提供されるデータベース、主なものでいえば、MySQL、PosgreSQL、Microsoft SQL Sever、H2 Databaseのようなデータベースにアクセスできます。
Domaの最近のバージョンで型安全にSQLを組み立てるための新しいAPI、Criteira APIが追加されました。この記事では、執筆時点で最新のバージョン2.43.0に基づいてCriteria APIを紹介します。
Doma入門の他の記事もお読みください。
エンティティクラスの定義
次のようなデータベーススキーマがあるとします。
create table employee (
id integer not null primary key,
name varchar(255) not null,
age integer not null,
version integer not null);
上記のテーブルに対応するエンティティクラスは次のように定義できます。
@Entity(metamodel = @Metamodel)
public class Employee {
@Id
public Integer id;
public String name;
public Integer age;
@Version public Integer version;
}
一見、通常のエンティティクラスの定義ですが、@Entity
の宣言にmetamodel = @Metamodel
という記述があることに注目してください。この記述がすごく重要で、適切な設定でコンパイルすることでEmployeeクラスと同じパッケージにEmployee_
というメタモデルクラスが生成されるようになります。
メモモデルクラスの中身
わかりやすさのために少し省略しますが、メタモデルクラスのEmployee_
は大体次のようなコードになります。
public final class Employee_ implements EntityMetamodel<Employee> {
public final PropertyMetamodel<java.lang.Integer> id = ...;
public final PropertyMetamodel<java.lang.String> name = ...;
public final PropertyMetamodel<java.lang.Integer> age = ...;
public final PropertyMetamodel<java.lang.Integer> version = ...;
}
このメタモデルクラスのポイントは、id
、name
、age
、version
のようにエンティティクラスのプロパティと同じ名前のプロパティを持っているということです。また、エンティティクラスにおけるプロパティの型情報を持っています。
これ以降は、このメタモデルクラスとCriteria APIを使って実際にSQLを組み立てる例を示します。
Criteria APIの利用
Criteria APIはどこでも利用できますが、例えば次のようにxxxRepositoryという名前のクラスを作ってその中で利用するとわかりやすいでしょう。
public class EmployeeRepository {
private final Entityql entityql;
public EmployeeRepository(Config config) {
this.entityql = new Entityql(config);
}
public Employee selectById(Integer id) {
// メタモデルの生成
Employee_ e = new Employee_();
// メタモデルを使ってSQLを組み立て結果を取得
return entityql.from(e).where(c -> c.eq(e.id, id)).fetchOne();
}
}
上記クラスのselectById
メソッドの中身がCriteria APIの利用例です。このメソッドではメタモデルクラスとCriteria APIのエントリーポイントであるEntityql
クラスを使ってSQLを組み立て実行結果を1つのエンティティとして取得しています。
組み立てられるSQLは次のようなものになります。
select t0_.id, t0_.name, t0_.age, t0_.version from Employee t0_ where t0_.id = ?
型安全の観点で言うと、WHERE句を組み立てるwhere(c -> c.eq(e.id, id))
の中のeq
メソッドがポイントです。このメソッドはジェネリクスを活用し、第1引数の型から第2引数の型をコンパイル時に決定しています。
つまり、この例では、eq
メソッドの第1引数にメタモデルクラスのInteger
型を表すプロパティを渡すことで第2引数の型をInteger
型に決定しています。したがって、例えば、c.eq(e.id, "String value")
のように第2引数に誤った型を渡してしまうこと(結果として実行時にエラーを発生させること)を防いでいます。
おわりに
エンティティを取得する例を使って、DomaのCriteri APIにより型安全にSQLを組み立てられることを示しました。
ここで示したコードと同等のものは、下記のプロジェクトから入手できます。