Select

selectを使用すると、グラフのルートレベルでフェッチされるプロパティを制御できます。一部のプロパティのみフェッチするように指定できます。結果は部分的に取り込まれたビーンです。

// "alias" bean that can be used in select and fetch clauses
QCustomer cust = QCustomer.alias();

List<Customer> customers =
  new QCustomer()
    // only fetch some properties of customer (partial objects)
    .select(cust.name, cust.version, cust.whenCreated)
    .name.istartsWith("Rob")
    .findList();

上記では、フェッチするプロパティを指定します。顧客エンティティビーンが返されますが、それらは部分的に取り込まれます

上記のクエリによって生成されるSQLには次のものがあります。

select t0.id, t0.name, t0.registered, t0.version from customer t0

@Idプロパティはほとんどのクエリに対して自動的に含まれ、distinctfindSingleAttribute、およびaggregationクエリに対して自動的に除外されることに注意してください。

クエリビーンを使用して選択プロパティを定義すると、オブジェクトグラフのどの部分をフェッチするかをタイプセーフに定義できます。

クエリ式APIを使用して記述された同じクエリは次のようになります。

List<Customer> customers =
  database.find(Customer.class)
    .select("name, registered, version")
    .findList();

alias() - プロパティを指定する

各クエリビーンには、select()およびfetch()でフェッチするプロパティを指定するために使用するクエリビーンを返す、静的なalias()メソッドがあります。

// customer "alias"
QCustomer cust = QCustomer.alias();

// contact "alias"
QCustomer con = QContact.alias();

List<Customer> customers =
  new QCustomer()

    .select(cust.name, cust.version, cust.whenCreated)
    .contacts.fetch(con.firstName, con.LastName, con.email)

    .name.istartsWith("Rob")
    .findList();

上記では、顧客と連絡先に対してエイリアスビーンがあります。これらを使用して、フェッチする特定のプロパティを指定します。

alias()を静的な最終フィールドに割り当てることができることに注意してください。

private static final QCustomer CUST = QCustomer.alias();
...
List<Customer> customers =
  new QCustomer()
    .select(CUST.name)
    .name.istartsWith("Rob")
    .findList();

静的インポート用のエイリアス

alias()メソッドの代わりとして、各クエリビーンは、静的インポートを使用する場合にAliasクラスも提供します。

たとえば、次のようにQCustomer.Aliasを使用して、顧客のプロパティを指定できます。

List<Customer> customers =
  new QCustomer()

    .select(QCustomer.Alias.name, QCustomer.Alias.whenCreated)
    .findList();

次に、これらを変更して次のような静的インポートを使用できます。

import static org.domain.query.QCustomer.Alias.name;
import static org.domain.query.QCustomer.Alias.whenCreated;
...


List<Customer> customers =
  new QCustomer()

    .select(name, whenCreated) // using static imports of QCustomer.Alias
    .findList();

このようなAliasを使用する場合の制限は、複数のクエリビーンタイプ(QCustomer.AliasとQContact.Aliasなど)に対してこれを実行すると、名前の衝突が発生する可能性があることです。たとえば、両方にwhenCreatedというプロパティがある場合、静的にインポートできるのはそのうち1つだけです。

import static ...query.QCustomer.Alias.name;
import static ...query.QCustomer.Alias.version;
import static ...query.QCustomer.Alias.whenCreated;
import static ...query.QContact.Alias.firstName;
import static ...query.QContact.Alias.lastName;

// Use explicit QContact.Alias.whenCreated (as clash with QCustomer.Alias.whenCreated)

List<Customer> customers =
  new QCustomer()
    .select(name, version, whenCreated)
    .contacts.fetch(firstName, lastName, QContact.Alias.whenCreated)

    .name.istartsWith("Rob")
    .findList();

数式

数式を指定する場合、この文字列選択句を使用する必要があります。

// java
List<String> names =
  new QContact()
    .select("concat(lastName,', ',firstName)")
    .lastName.startsWith("A")
    .findSingleAttributeList();
// kotlin
var names: List<String> =
  QContact()
    .select("concat(lastName,' ',firstName)")
    .lastName.startsWith("A")
    .findSingleAttributeList()
例: Postgis ST_Distance 数式

この例では、数式末尾の::BigDecimalキャストを使用して、明示的にJava BigDecimal型にキャストします。

// given route is a Postgis geometry(linestring,4326)
// return the distance between the start and end points

BigDecimal routeDistance = query()
  .select("ST_Distance(ST_StartPoint(route), ST_EndPoint(route))::BigDecimal")
  .where()
  .idEq(tripId)
  .findSingleAttribute();

asDto

数式を選択する場合、エンティティビーンではなくプレーンなDTOビーンに結果を返したい場合があります。ORMクエリをDtoQueryに変換するには、.asDto(Class<D>)を使用します。

詳細は、DTOクエリを参照してください。

// ContactDto is a plain bean with email and fullName properties

List<ContactDto> contacts =
  new QContact()
    .select("email, concat(lastName, ', ', firstName) as fullName")
    .lastName.startsWith("A")
    .orderBy()
       .lastName.asc()
    .setMaxRows(10)
    .asDto(ContactDto.class)
    .findList();

Aggregation

数式クエリと同様に、SUM、MAX、MIN、AVG、COUNTの標準集計を選択句で使用できます。

詳細は、集計クエリを参照してください。

単一集計クエリ
// java
Timestamp maxWhen  =
  new QContact()
    .select("max(whenModified)")
    .findSingleAttribute()
// kotlin
var maxWhen: Timestamp =
  QContact()
    .select("max(whenModified)")
    .findSingleAttribute()
select max(t0.when_modified) from contact t0
グループ別集計クエリ

複数列集計クエリでは、文字列選択句を使用します。

List<MachineStats> result =
  new QMachineStats()
  .select("machine, date, max(rate)")
  .date.gt(LocalDate.now().minusDays(10))
  .query().having().gt("max(rate)", 4)
  .findList();

上記のクエリは、次のsqlを生成します。

select t0.machine_id, t0.date, max(t0.rate)
from d_machine_stats t0
where t0.date > ?
group by t0.machine_id, t0.date
having max(t0.rate) > ?