DataBase API Drupal 7.Работа с базой данных в седьмом друпале.

Опубликовано 2011.10.27 в разделе Drupal

В седьмом друпале для работы с базой данных можно использовать специальное API. Его преимущества-это:простота написания кода,кроссплатформенность написаных запросов, сведение к минимуму ошибок. Из личного опыта:было написано порядка 10 сложных самописных модулей, написаных с использованием DataBase API Drupal 7, и работающих на MySql. После переноса сайта на MsSql, с использование технологии Microsoft Azure - потребовалось внести мелкие поправки всего в несколько запросов,а не переписывать по 10-20 запросов в каждом модуле. Примеры работы в шестой версии Drupal рассматривать не будем, только для 7. Вначале посмотрим на основные методы,а далее уже рассотрим полноценные запросы:
  1. //Выборка данных
  2. db_select('table_name','t');
  3.  
  4. //апдейт
  5. db_update('table_name');
  6.  
  7. //удаление
  8. db_delete('table_name');
  9.  
  10. //вставка
  11. db_insert('table_name');
Пояснение:всем этим четырем функциям вкачестве первого аргумента передается название таблицы, без префикса. В первом случае,с выборкой, вторым аргументом указывается псевдоним данный таблицы,он обязателен даже при выборке из одной таблицы. Указывайте любой, например первая буква в названии таблицы.
  1. //оператор условия
  2. condition('ячейка','значение','оператор');
Это замена привычного вам where.
  1. //Тоесть если надо написать чтото типа
  2. where table.user_id=50
  3.  
  4. //То пишем:
  5. condition('table.user_id',50,'=');
По умолчанию знак равенства можно не ставить.Но если нужно использовать оператор больше,меньше,меньше или равно и т.п. - вместо знака "=" ставите ">" , к примеру. Но и привычный where никто не запрещал.Используется так,тут попроще.
  1. where('YEAR(FROM_UNIXTIME(date_1)) = :my_data', array(':my_data' => 2012));
В объяснении, думаю, не нуждается. Выборка полей,оператор fields:
  1. fields('псевдоним таблицы',array('поле_1','поле_2'));
  2. //например
  3. fields('o',array('DateTimeStart','UserID'));
Вот тут и указывается псевдоним,о котором мы говорили ранее. Сортировка:
  1. orderBy('ячейка','порядок сортировки');
  2. //например
  3. orderBy('o.DateTimeStart','asc');
Группировка:
  1. groupBy('ячейка_1 , ячейка_2');
  2. //например
  3. groupBy('o.DateTimeStart, o.UserID');
Подсчет количество строк:
  1. addExpression('count(*)','псевдоним');
  2. //например
  3. addExpression('count(*)','total_views');
Условия в запросе:
  1. addExpression('условие','псевдоним');
  2. //например
  3. addExpression('if(i.nid>0,1,0)','est');
  4. //пояснение: если поле nid из таблицы с псевдонимом i больше 0, то
  5. //ячейка est будет равна 1, иначе 0.
Выборка из нескольких таблиц-он же join
  1. leftJoin('имя таблицы','её псевдоним','условие');
  2.  
  3. //подробнее. на sql
  4. left join 'table_2' as t2
  5. on t2.pole=t1.znach
  6.  
  7. //на drupal это выглядит вот так
  8. leftJoin('table_2','t2','t2.pole=t1.znach');
  9.  
  10. //тоесть джоиним таблицу table_2 по полю pole
  11. //точно также используются rightJoin и innerJoin
Выполнение запроса
  1. execute();
Вот в основном это всё.Теперь как это всё работает.
  1. //устанавливаем связь с таблицей cb_stats_sess
  2. $q=db_select('cb_stats_sess','s');
  3.  
  4. //пишем условие
  5. $q->condition('s.PlayerID',15,'>=');
  6.  
  7. //выбираем поля
  8. $q->fields('s',array('UserName','UserID','DateRegister'));
  9.  
  10. //сортируем по дате регистрации
  11. $q->orderby('s.DateRegister');
  12.  
  13. //отрабатываем запрос
  14. $res=$q->execute();
  15.  
  16. //отображаем данные
  17. while($rec=$res->fetchAssoc()){
  18. echo $rec['UserName'].' - '.$rec['DateRegister'].' : '.$rec['UserID'].'<br />';
  19. }
Вот в принципе и всё. Оператор having, например, тоже очень легко отрабатывается. Оператор limit. Заменен на range
  1. range(0,'количество');
  2. //например извлечь первые 30 записей
  3. range(0,30);
Я приведу пример нескольких реальных запросов,чтоб на примере вам было понятно как всё это действует: Простая выборка данных:
  1. // соединение с бд,подключение пагинации
  2. $q =db_select('cb_stats_sessionss','s')->extend('PagerDefault');
  3.  
  4. //джоиним таблицы
  5. $q ->leftjoin('cb_stats_videos', 'v', 's.VideoID = v.ID');
  6. $q ->leftjoin('cb_node_guid','ng','ng.guid=v.AvsURL');
  7. $q ->leftjoin('node', 'n', 'n.nid = ng.nid');
  8.  
  9. //условия
  10. $q ->condition('s.PlayerID',$player_list,'=');
  11. $q ->condition('s.DateTimeStart',$day_first_int,'>');
  12. $q ->condition('s.DateTimeStart',$day_end_int,'<');
  13. $q ->condition('n.title','','<>');
  14.  
  15. //извлекаемые поля
  16. $q ->fields('s',array('VideoID'));
  17. $q ->fields('v',array('AvsURL'));
  18. $q ->fields('n',array('title'));
  19.  
  20. $q ->addExpression('count(*)','views');
  21. $q ->addExpression('count(distinct s.UserID)','uniques');
  22.  
  23. //группировки
  24. $q->groupBy('s.VideoID');
  25. $q->groupBy('v.AvsURL');
  26. $q->groupBy('n.title');
  27.  
  28. //сортировки
  29. $q->orderBy('views','desc');
  30. $q->orderBy('uniques','desc');
  31.  
  32. //выполнение запроса
  33. $result = $q->range(0, 20)->execute();
  34.  
  35. $rows = array();
  36.  
  37. while($record=$result->fetchAssoc()){
  38. $rows[]=array(
  39. array('data'=>'<a href="my_url/video_id/'.$record['VideoID'].'" >'.$record['title'].'</a>'),
  40. array('data'=>$record['views']),
  41. array('data'=>$record['uniques']),
  42. array('data'=>'<a rel="lightframe" href="clickberry_statistic_flash/'.$record['VideoID'].'" >View graph</a>'),
  43. );
  44. }
  45. </');>
  1. $q=db_update('cb_services_dir');
  2. $q->fields(array('name' => $dirname,'par_id'=>$dir_parentid));
  3. $q->condition('id', $dir_id);
  4. $q->execute();
  1. $q=db_delete('cb_services_comments_child');
  2. $q->condition('srv_id', $comm_id);
  3. //обратите внимание на оператор in.В переменной $commn должен быть не список значений через запятую,а массив этих значений.
  4. $q->condition('id', $commn,'in');
  5. $q->execute();
  1. $fields = array(
  2. 'user_id' => $user->uid,
  3. 'created' => $created,
  4. 'string_id' => $string_id,
  5. 'name' => $name,
  6. 'directory' => $dir,
  7. 'title' => $title,
  8. 'options' => $options_str,
  9. 'lang' => $service_lang
  10. );
  11. db_insert('cb_services_poll')->fields($fields)->execute();
  1. $q =db_select('cb_stats_objects','o');
  2. $q ->condition('o.VideoID',$v_id,'=');
  3. $q ->leftjoin('cb_stats_clicks', 'c', 'o.ID = c.ObjectID');
  4. $q ->fields('o',array('ObjectName','ObjectURL'));
  5. $q ->addExpression('count(*)','clicks');
  6. $q ->groupBy('o.ID,o.ObjectName,o.ObjectURL');
  7. $q ->orderBy('clicks','desc');
  8. $result=$q->execute();

7 Комментариев

Оставить комментарий

  1. Гость 2016/07/17

    Начать наверное нужно с добавления в базу данных? статья никчемна!

    Ответить

    1. Админ 2016/07/19

      Интересные у вас критерии...

      Ответить

  2. Гость 2015/11/12

    Здравствуйте!

    Посоветуйте как избежать конфликта в БД.
    В одной базе содержатся таблицы Друпал и форума phpbb. Таблицы с разными префиксами. Подключаться к базе напрямую - ламерство.
    Для разноименных таблиц работает конструкция в settings.php
    'driver' => 'mysql',
    'prefix' => array(
    'default' => 'dr7_',
    'table1' => 'phpbb_',
    'table2' => 'phpbb_',
    )
    Но имеются 2 таблицы users. В запросах префиксы не указываются, соответственно имеет место конфликт одноименных таблиц.
    Как это можно решить?

    Ответить

    1. Гость 2015/11/13

      Проблема решена.
      Использовал представления mysql

      Ответить

  3. Гость 2014/11/21

    Хорошая статья Вери-биг-сенкс

    Ответить

  4. Гость 2013/01/07

    Хорошие примеры, Спасибо!

    Ответить

  5. Гость 2012/09/11

    Здравствуйте.
    У вас опечатка, в тексте вы пишете что "Оператор limit. Заменен на range", а в примере используете "limit".
    Спасибо за статью!

    Ответить

Ваш комментарий успешно создан

Ваш комментарий

  • Для выделения кода оберните его в тэги <code> и </code>
  • Отметьте телефон