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
プロパティはほとんどのクエリに対して自動的に含まれ、distinct、findSingleAttribute、および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) > ?