Конструктор запросов: общая информация

Класс JDatabaseQuery позволяет создавать SQL-запросы в объектно-ориентированном виде.

Методы класса инкапсулируют язык запросов, скрывая специфический синтаксис. При этом они могут складываться в цепочку, что значительно упрощает код и улучшает его читаемость. Это своего рода конструктор, где отдельные детали (методы) образуют единую конструкцию (запрос).

Давайте кратко рассмотрим принцип работы с конструктором запросов.

Для начала работы необходимо получить его объект, используя метод getQuery() класса JDatabaseDriver:

$query = Factory::getDbo()
    ->getQuery(true);

Экранирование строк и идентификаторов запроса

Для экранирования строк и идентификаторов запроса в конструкторе запросов предусмотрено три метода. Все они являются прокси-методами для соответствующих методов драйвера базы данных JDatabaseDriver:

  • quoteName($name, $as = null) - оборачивает идентификаторы запроса (названия таблиц и полей) в кавычки;
  • escape($text, $extra = false)- добавляет обратную косую черту перед небезопасными символами;
  • quote($text, $escape = true) - добавляет обратную косую черту перед небезопасными символами и оборачивает строку в одинарные кавычки.

Подробнее об экранировании: quoteName и escape / quote.

Составление запросов

Вот так выглядит типичный запрос:

$query->select($query->quoteName('title'));
$query->from($query->quoteName('#__content'));
$query->where($query->quoteName('state') . ' = 1');

Если перевести этот запрос в строку, то он будет выглядеть следующим образом:

SELECT `title` FROM `#__content` WHERE `state` = 1

Мы можем использовать цепочку методов:

$query->select($query->quoteName('title'))
    ->from($query->quoteName('#__content'))
    ->where($query->quoteName('state') . ' = 1');

Добавим ещё одно условие, например ID автора:

$query->select($query->quoteName('title'))
    ->from($query->quoteName('#__content'))
    ->where($query->quoteName('state') . ' = 1')
    ->where($query->quoteName('created_by') . ' = 839');
SELECT `title` FROM `#__content` WHERE `state` = 1 AND `created_by` = 839

Конструктор позволяет добавлять различные условия в разном порядке:

// Выбираем значения из #__content
$query->select('a.*');
    ->from($query->quoteName('#__content', 'a'));
    ->where($query->quoteName('a.state') . ' = 1');
    ->where($query->quoteName('a.created_by') . ' = 839');
// Присоединяем #__users
$query->select($query->quoteName('b.username'))
   ->leftJoin(
        $query->quoteName('#__users', 'b') 
        . ' ON ' 
        . $query->quoteName('b.id') 
        . ' = '
        . $query->quoteName('a.created_by')
    );
// Сортируем по title
$query->order($query->quoteName('a.title') . ' ASC');

Запрос на выполнение всё равно будет составлен корректно:

SELECT a.*,`b`.`username`
FROM `#__content` AS `a`
LEFT JOIN `#__users` AS `b` ON `b`.`id` = `a`.`created_by`
WHERE `a`.`state` = 1
AND `a`.`created_by` = 839
ORDER BY `a`.`title` ASC

При составлении запросов важно помнить следующее: нельзя смешивать в одном запросе select и insert, update, delete.

Ссылки по теме

© 2019 BinaryCraft. Все права защищены.