こんにちは。

8月も終盤に差し掛かり、最近少し涼しさを感じてきたかなと喜んでいた束の間、夏バテと気温の変化にやられて体調を崩してしまった西岡です。

皆さんも夏バテと気温の変化が出てくる時期なので、体調の変化にはくれぐれもお気をつけください。

さていきなりではありますが、今回は自分の復習も兼ねてDatabase APIについての記事を書きたいと思います。

まずは、Database APIの概要からご説明していきたいと思います。

このAPIはSQL構文とDatabaseの制御または管理するSQLの特徴を可能な限り保持するように設計されており、SQL構文の知識がある人であれば、これらを用いることでDatabaseに接続できるようになります。また複数のDatabaseサーバーを簡単にサポートしてくれるなどの機能もあります。

Database APIはオブジェクト指向の設計コンセプトで構築されているため、少なくともオブジェクト指向の概念を部分的に理解していることが前提とされています。一般的な操作でも使用できる手続き型スタイルもありますが、これは非推奨とされており、Databaseの操作には接続オブジェクトを使用することが推奨されています。

また、Database APIはデータとのやり取りに関して、最適な手段ではない場合があります。Drupal8でのAPIの使用は、Drupal8 APIsなどを参考にして、ニーズに最も適したAPIを使用していく必要があることは覚えておいた方が良いと思われます。

では、今回は推奨されている接続オブジェクトを用いた方法でDatabaseに接続して行きたいと思います。

まずはDatabase接続を定義する主な手段は、settings.phpの$databases配列です。これらは複数のDatabase接続の定義を可能にしており、ここに定義されたDatabaseに接続します。

settings.phpsites/defaultの下にあり、そのファイルを開くと、Drupal8をインストールしたときに登録したDatabaseの情報が以下のように記載されていると思います。

$databases['default']['default'] = array(
  'database' => 'データベース名',
  'username' => 'ユーザー名',
  'password' => 'パスワード',
  'host' => 'ホスト名',
);

複数のデータベースを接続するのであれば、2つ目のdefaultキーを変更して$Database配列として記載されている必要があります。

$databases['default']['default'] = array(
  'database' => 'データベース名',
  'username' => 'ユーザー名',
  'password' => 'パスワード',
  'host' => 'ホスト名',
);

$databases['default']['example'] = array(
  'database' => 'データベース名2',
  'username' => 'ユーザー名',
  'password' => 'パスワード',
  'host' => 'ホスト名2',
);

では、Databaseに接続していきましょう。

まずは例となるコードを先に提示しておきます。今回はnodeテーブルnode_field_dataテーブルと内部結合させ、指定した条件と合致するnidを取得するということを行いたいと思います。

$db = \Drupal::database();
$query = $db->select('node', 'n');
$query->join('node_field_data', 'd', 'd.nid = n.nid');

$nids = $query
  ->fields('n', ['nid'])
  ->condition('n.type', 'article')
  ->condition('d.title', 'test')
  ->execute()
  ->fetchCol();

まずは接続オブジェクトをインスタンス化するコードは以下になります。上記でも説明したように、Drupal8では接続オブジェクトを介してDatabaseとのやり取りが推奨されているため、接続オブジェクトをインスタンス化する必要があります。

$db = \Drupal::database();

次に、接続オブジェクトを$dbに格納し、そこからselectメソッドを呼び出してテーブルの情報を記載します。左がテーブル名、右がそのテーブル名のエイリアスを設定しています。 そこからjoinメソッドを呼び出し、結合させたいテーブルとエイリアス、結合させたい条件を記載します。今回はnodenidnode_field_datanidが一緒という条件をもとに結合させています。

$query = $db->select('node', 'n');
$query->join('node_field_data', 'd', 'd.nid = n.nid');

ここまでできたら、次はnode_field_dataを結合したnodeテーブルからnidを取得して$nidsという変数に格納するまでの動きを説明していきます。

まずfieldsメソッドを呼び出し、どこのテーブルの何を取得したいかを記述します。今回はnodeテーブルから該当する条件のnidを取得したいので、エイリアス名とnidと記述します。そこから取得したnidの条件を記載していきます。条件を絞り込むのはconditionメソッドを使用します。SQL文で言うwhereだと思っていただければ分かりやすいかと思います。conditionメソッドではnodeテーブルのtypeがarticle、そしてnode_field_dataのtitleがtestを指定しています。conditionメソッドの3つ目には比較演算子を使用することで、さらに細かい条件を指定することができます。

そこまでできたらexecuteメソッドで実行し、fetchColで指定した条件に合致するnidを配列にして返すという流れになります。

$nids = $query
  ->fields('n', ['nid'])
  ->condition('n.type', 'article')
  ->condition('d.title', 'test')
  ->execute()
  ->fetchCol();

今回のDatabase APIを用いたコードをSQL文に直すと

select n.nid from node as n join node_field_data as d 
on n.nid = d.nid where n.type = 'article' and d.title = 'test';

とこんな感じでしょうか。これをDrupal8のDatabase APIを用いると例のコードになると言ったところです。

いかがでしたでしょうか。今回は自分の復習も兼ねての簡単な内容の記事だったので、皆さんご存知であるかたも多いと思うのですが、もし初めてという方がいらっしゃったら参考にしてもらえると嬉しいです。

その他にもupdateメソッド、deleteメソッド、insertメソッドなど、SQLと同様なことが行えるメソッドもありますので、それらをこれから勉強していきたいと思っております。それをまた記事にできる機会があればしていきたいと思いますので、これからもDrupal8について学んで行きたいと思います。目を通していただき、ありがとうございました。