Построение запросов с использованием Database API

Версия Друпала:
7.x

Одним из весомых преимуществ Drupal 7 над его предшественниками есть его гибкость к настройкам и системам. Разработчики не обошли стороной и запросы к БД. В этом релизе они стали объектно-ориентированными и не привязанными к конкретной базе дынных, поскольку теперь сам Drupal генерирует синтаксис запроса. Задачею программиста остается лишь указать условия выборки. Эту статью я посвящаю анализу Database API, где приведу примеры как именно изменилось “общение” с БД.

  Первым делом хотелось бы заметить, что изменился и синтаксис подключения сайта к базе. От привычного нам

<?php
$db_url 
'mysqli://username:password@localhost/basename';
?>

к более читабельному

<?php
$databases
['default']['default'] = array(
  
'driver'   => 'mysql',
  
'database' => 'basename',
  
'username' => 'username',
  
'password' => 'password',
  
'host'     => 'localhost',
);
?>

   Хочу заметить, что Drupal 7 все еще поддерживает db_query(), но его коснулись кое-какие изменения - изменились заменители (placeholders). Одним из вариантов есть использования знака ? вместо %d, ’%s’. В этом случае значения таких заменителей указываются в массиве после запроса в том же порядке, в каком они расположены в запросе:

<?php
db_query
("SELECT `title` FROM {node} WHERE `uid` = ? AND `type` = ?", array(1'page'));
?>

   Другой вариант - использование так званых “именных” заменителей. Подстановка значений происходит в ассоциативном массиве. Один и тот же заменитель не может быть описан дважды, даже если он будет иметь то же значение. Принято их называть соответствующими колонками таблиц, значения которых они определяют:

<?php
db_query
("SELECT `title` FROM {node} WHERE `uid`= :uid AND `type` = :type", array(':uid' => 1':type' => 'page'));
?>

   Но вернемся все таки к нашей теме, и рассмотрим новшества в этой области. Если раньше мы использовали db_query() и внутри него прописывали необходимый тип запроса (select, insert, update, delete), то теперь каждому из них соответствует своя функция (db_select(), db_insert(), db_update(), db_delete()), на основе которой и генерируется необходимый синтаксис. Список допустимых функций:

  • db_and
  • db_close
  • db_condition
  • db_delete
  • db_driver
  • db_escape_field
  • db_escape_table
  • db_insert
  • db_like
  • db_merge
  • db_next_id
  • db_or
  • db_query
  • db_query_range
  • db_query_temporary
  • db_select
  • db_set_active
  • db_transaction
  • db_truncate
  • db_update
  • db_xor

  Определение формата данных, полученных в ходе выполнения обращения к базе, тоже потерпело изменений. На смену таких функций, как db_result(), db_fetch_array(), db_fetch_object() и т. д., пришли методы класса DatabaseStatementInterface:

  • execute - выполнение запроса;

  • fetchAllAssoc - возвращает результат запроса в виде ассоциативного массива ключей заданного поля;
  • fetchAllKeyed - возвращает результат как единый ассоциативный массив;
  • fetchAssoc - выбирает следующую строку и возвращает её в качестве ассоциативного массива;
  • fetchCol - возвращает один столбец результирующего набора, как индексированный массив;
  • fetchField - возвращает одно поле из следующей записи из результирующего набора;
  • getQueryString - возвращает строку запроса;
  • rowCount - возвращает число строк, которые возвращает запрос.

   Необходимым условием выполнения запроса является присутствие execute(). Он должен быть использован перед определением формата.

    Теперь рассмотрим как все это работает. Создадим запрос, который вернет нам содержимое таблицы `node`:

<?php
$result 
db_select('node''n')
  ->
fields('n')
  ->
execute()
  ->
fetchAssoc();
?>

   В db_select необходимо указать таблицу, и при необходимости ее сокращение, с которой будет осуществляться выборка. Далее, добавляем метод fields(), в котором указываем таблицу и поля для выборки. Если поля не указанны, то запрос вернет все поля таблицы (аналог *). Execute() обеспечит выполнение нашего запроса, а fetchAssoc() вернет результат в виде ассоциативного массива. Указывая необходимые поля, нужно учесть одну особенность - они должны быть перечислены в массиве, даже если указывается лишь одно поле!

    Если же в нашем запросе необходимо указать некое условие, то для этого нам необходимо использовать метод conditions(). Он принимает три значения - поле, значение поля, параметр сравнения. Если не указан последний, то по-умолчанию он определиться как “=”.

<?php
$result 
db_select('node''n')
  ->
fields('n', array('type''tittle'))
  ->
condition('nid'$node->nid'=')
  ->
condition('status'0'>')
  ->
condition('uid', array(157), 'IN')
  ->
execute()
  ->
fetchAssoc();
?>

   Есть также и другие методы запроса, которые позволяют делать сложение таблиц (join), группировку значений (groupBy), их сортировку (orderBy), ограничение количества результатов (range) и др. Все они, в своем сочетании, позволяют строить сложные запросы к БД.

   Приведем пример создания запроса для выборки значений из нескольки таблиц, используя группировку и сортировку, ограничив число результатов:

<?php
$query 
db_select('node''n');
$query->join('users''u''n.uid = u.uid');
$query->groupBy('u.uid');
$query->fields('n', array('title''created'))
  ->
fields('u', array('name'))
  ->
orderBy('created''DESC')
  ->
range(010);
$result $query->execute();
while (
$record $result->fetchAssoc()) {
   
print_r ($record);
}
?>

    По такому принципу работают все запросы. Для подтверждения этих слов, приведем примеры использования запросов для вставки и удаления записей:

<?php
$id 
db_insert('node')->fields(array(
  
'title'   => 'Title',
  
'uid'     => 1,
  
'created' => REQUEST_TIME,
))->
execute();
?>

<?php
db_delete
('node')
  ->
condition('uid'5)
  ->
condition('created'time() - 3600'<')
  ->
execute();
?>

    Database API, реализованый в Drupal 7, позволяет строить объемные запросы, имеет большую скорость их обработки, лучшую читабельность и возможность внесения изменений, а также самостоятельно строит синтаксис запроса, уменьшая таким образом к минимуму возможность пользователем совершить ошибку в структуре и не привязывается к одной базе данных, что гарантирует возможность выполнения запроса для разных БД.

     Вы можете ознакомиться со сравнениями построения запросов в Drupal 6 и 7, на основе презентации. Смотреть

 

Тэги:
Database API, Drupal 7