LoginSignup
8
5

More than 3 years have passed since last update.

Doma入門 - Criteria APIの紹介

Last updated at Posted at 2020-09-28

はじめに

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 = ...;
}

このメタモデルクラスのポイントは、idnameageversionのようにエンティティクラスのプロパティと同じ名前のプロパティを持っているということです。また、エンティティクラスにおけるプロパティの型情報を持っています。

これ以降は、このメタモデルクラスと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を組み立てられることを示しました。

ここで示したコードと同等のものは、下記のプロジェクトから入手できます。

8
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5