挿入クエリは常にクエリビルダーオブジェクトを使用する必要があります。一部のデータベースでは、LOB(Large OBject、例:MySQLのTEXT)およびBLOB(Binary Large OBject)フィールドの特別な処理が必要です。したがって、個々のデータベースドライバーが必要な特別な処理を実装できるように、抽象化レイヤーが必要です。
挿入クエリはinsert()メソッドを使用して次のように開始します:
$query = $connection->insert('mytable', $options);
これにより、mytableテーブルに1つ以上のレコードを挿入する挿入クエリオブジェクトが作成されます。テーブル名に中括弧は不要です。クエリビルダーが自動的に処理するためです。
挿入クエリオブジェクトは流れるようなAPIを使用します。つまり、execute()を除くすべてのメソッドがクエリオブジェクト自体を返すため、メソッド呼び出しを連結できます。多くの場合、これはクエリオブジェクトを変数に保存する必要がまったくないことを意味します。
クエリの結果は、カスタムクラスに基づくオブジェクトに取得できます。たとえば、ExampleClassという名前のクラスがある場合、次のクエリはexampleClass型のオブジェクトを返します。
$result = $connection->query("SELECT id, title FROM {example_table}", [], [
'fetch' => 'ExampleClass',
]);
クラスに__construct()メソッドがある場合、オブジェクトが作成され、プロパティがオブジェクトに追加され、その後__construct()メソッドが呼び出されます。たとえば、次のクラスとクエリがある場合です。
SELECTクエリは常に、0件以上のレコードを含む結果セットオブジェクトを返します。使用ケースに応じて、この結果セットからデータを取得する方法はいくつかあります。取得モードを変更しない限り(setFetchModeを参照)、レコードはデフォルトでオブジェクトとして取得されます。
最も一般的なケースは、foreach()ループで結果セットを反復処理することです。
動的クエリにWHERE句を追加するには、condition()メソッドを使用します:
$query->condition('bundle', 'article', '=');
上記のコードは、クエリにarticleバンドルの結果をフィルタリングするよう指示します。ここでのフィールド名は、addField()またはaddExpression()メソッドで作成されたエイリアスである必要があることに注意してください。
Conditionパラメーター
condition()メソッドは3つのパラメーターを受け取ります:
- $field - 比較するフィールド(必須)。
- $value - 比較する値(オプション、デフォルトはNULL)。
- $operator - 比較演算子(オプション、デフォルトは'=')
サポートされている演算子
一般的な比較演算子'='、'<>'、'<'、'<='、'>'、'> ='は、サポートされているすべてのデータベースタイプでサポートされています。
指定されたフィールドでグループ化するには、groupBy()メソッドを使用します。
$query->groupBy('uid');
上記のコードは、クエリにuidフィールドでグループ化するよう指示します。ここでのフィールド名は、addField()またはaddExpression()メソッドで作成されたエイリアスである必要があることに注意してください。したがって、ほとんどの場合、正しいエイリアスが使用されるように、これらのメソッドの戻り値を使用する必要があります。
たとえばuidなどのフィールドでグループ化された行数を取得するには、次のようにします:
$query->addExpression('count(uid)', 'uid_node_count');
複数のフィールドでグループ化するには、必要な順序でgroupBy()を複数回呼び出すだけです。
Having
集計値に条件を追加できます。
一部のSQLクエリは重複する結果を返す場合があります。そのような場合、重複する行は静的クエリの「DISTINCT」キーワードを使用してフィルタリングできます。動的クエリでは、distinct()メソッドを使用します。
// Force filtering of duplicate records in the result set.
$connection = \Drupal::database();
$query = $connection->select('my_table', 'mt');
$query->fields('mt', ['my_fields']);
$query->distinct()->execute()->fetchAll();
DISTINCTはパフォーマンスの低下を引き起こす可能性があることに注意してください。したがって、重複を避けるために結果セットを制限する他の方法がない場合を除き、使用しないでください。
どのクエリにも対応する「カウントクエリ」を設定できます。カウントクエリは、元のクエリの行数を返します。既存のクエリ(SelectInterfaceを実装するselectクエリオブジェクト)からカウントクエリを取得するには、countQuery()メソッドを使用します。
$count_query = $query->countQuery();
$count_queryは、順序付けのない新しい動的selectクエリになり、実行すると、元のクエリに一致するレコード数という単一の値のみを含む結果セットを返します。PHPは返されたオブジェクトのメソッドチェーンをサポートしているため、次のアプローチが一般的です:
$num_rows = $query->countQuery()->execute()->fetchField();
エンティティクエリ(QueryInterfaceを実装)の場合、コードは少し異なります:
フィールドを追加
SELECTクエリにフィールドを追加するには、addField()メソッドを使用します:
$title_field = $query->addField('n', 'title', 'my_title');
上記のコードは、クエリにエイリアス「n」を持つテーブルの「title」フィールドを選択し、「my_title」というエイリアスを割り当てるよう指示します。エイリアスが指定されていない場合は、自動的に作成されます。圧倒的多数の場合、生成されるエイリアスは単なるフィールド名です。この例では「title」になります。このエイリアスが既に存在する場合は、エイリアスはテーブル名とフィールド名になります。この例では「n_title」になります。このエイリアスも既に存在する場合は、未使用のエイリアスが見つかるまで(「n_title_2」など)エイリアスにカウンターが追加されます。
SELECTクエリビルダーは、フィールドリストでの式の使用をサポートしています。式の例には、「ageフィールドの2倍」、「nameフィールドすべてのカウント」、「titleフィールドの部分文字列」などがあります。多くの式はSQL関数を使用でき、すべてのSQL関数がすべてのデータベースで標準化されているわけではないことに注意してください。モジュール開発者は、データベースと互換性のある式のみを使用することを確認する必要があります。(関数と演算子のリストを参照)
クエリに式を追加するには、addExpression()メソッドを使用します。
動的クエリとは、明示的なクエリ文字列として提供されるのではなく、Drupalによって動的に作成されるクエリを指します。すべての挿入、更新、削除、マージクエリは動的である必要があります。選択クエリは静的または動的にすることができます。したがって、「動的クエリ」は通常、動的SELECTクエリを指します。
注:selectクエリの使用の90%は静的クエリになります。パフォーマンスが重要なパスでは、パフォーマンス上の理由からselect()の代わりにquery()を使用する必要があります。動的クエリは、クエリの一部が異なる場合(例:コンテキストに応じてWHERE条件を追加する)または変更可能である必要がある場合にのみ使用します。
動的に作成されるすべてのクエリは、対応するデータベース接続オブジェクトから要求されたクエリオブジェクトを使用して作成されます。静的クエリと同様に、圧倒的多数の場合、プロシージャルラッパーをクエリオブジェクトに使用できます。ただし、その後のクエリディレクティブは、クエリオブジェクトに対して呼び出されるメソッドの形式を取ります。
動的選択クエリは、select()メソッドを使用して次のように開始します: