JDatabase – вставка, обновление и удаление данных
Перед прочтением этого материала рекомендуем вам ознакомиться со следующими материалами:
Содержание
Вступление
Работу с базой данных условно можно разделить на две группы:
- выборка данных и получение результата
- вставка, обновление и удаление данных
В этом материале мы разберем, как с помощью методов группы классов JDatabase можно вставлять, обновлять и удалять данные.
Выборка данных и получение результата рассматривается в этом материале.
Вставка данных
Используя SQL
Класс JDatabaseQuery предоставляет несколько методов для вставки данных: insert(), columns() и values().
// Получаем объект коннектора базы данных $db = JFactory::getDbo(); // Получаем объект запроса $query = $db->getQuery(true); // Колонки для вставки $columns = array( 'user_id', 'profile_key', 'profile_value', 'ordering' ); // Значения для вставки $values = array( 42, $db->quote('custom.message'), $db->quote('Вставка данных с помощью insert()'), 1 ); // Составляем запрос $query->insert($db->quoteName('#__user_profiles')) ->columns($db->quoteName($columns)) ->values(implode(',', $values)); // Устанавливаем и выполняем запрос $db->setQuery($query) ->execute();
(Здесь функция quoteName() добавляет соответствующие кавычки вокруг имен таблицы и столбцов, чтобы избежать конфликтов с любым зарезервированным словом базы данных, сейчас или в будущем). Чтобы получить идентификатор только что вставленной строки, вы можете использовать, например, метод 'insertid'.
// Получить строку, которая была только что вставлена $new_row_id = $db->insertid();
Как сохранить пустое значение как NULL
Если значение столбца по умолчанию равно NULL, вам не следует добавлять это имя столбца в массив. Пусть система баз данных сохранит значение NULL в качестве значения по умолчанию. Если значение столбца по умолчанию не равно NULL и разрешено хранить нулевые значения, вы должны указать это в коде. Смотрите, как это сделать, в следующем примере.
// Получить подключение к базе данных. $db = JFactory::getDbo(); // Создать новый объект запроса. $query = $db->getQuery(true); /** Первый случай [значение по умолчанию - NULL] **/ // Столбец 'profile_value' имеет значение NULL // в качестве значения по умолчанию. Итак, мы не будем // добавлять его в массив. Компонент database engine сохранит // значение NULL в качестве значения для столбца 'profile_value'. $columns = array('user_id', 'profile_key', 'ordering'); // Вставить значения. $values = array(1001, $db->quote('custom.message'), 1); /** Второй случай [строка в качестве значения по умолчанию, // и вы также можете сохранить нулевое значение] **/ // Столбец 'profile_value' имеет пустую строку " // в качестве значения по умолчанию, но мы также можем // сохранить нулевое значение. Итак, мы должны добавить имя // столбца и нулевое значение в $columns и $values. $columns = array('user_id', 'profile_key', 'profile_value', 'ordering'); // Вставить значения. $values = array(1001, $db->quote('custom.message'), $db->quote('NULL'), 1);
Используя объект
Класс JDatabaseDriver предоставляет удобный метод insertObject($table, &$object, $key = null)
для сохранения объекта напрямую в базу данных:
$table
– имя таблицы&$object
– объект, публичные свойства которого соответствуют полям в таблице$key
– первичный ключ
В случае если мы передаем третий параметр, то свойству $key
объекта присваивается значение идентификатора последней вставленной записи.
Метод insertObject()
автоматически экранирует данные: применяет quoteName()
к имени таблицы и колонкам, а также quote()
к значениям.
// Создаем и заполняем объект $profile = new stdClass(); $profile->user_id = 42; $profile->profile_key = 'custom.message'; $profile->profile_value= 'Вставка данных с помощью insertObject()'; $profile->ordering = 1; $db = JFactory::getDbo(); // Вставляем объект в таблицу профиля пользователя $result = $db->insertObject('#__user_profiles', $profile);
Метод возвращает true
, если вставка прошла успешно, в противном случае false
.
Ещё раз!!! (для тупых). Методы insert и insertObject находятся в РАЗНЫХ классах, и соответственно в разных объектах. Метод insert находится в классе JDatabaseQuery (объект $query), а метод insertObject в классе JDatabaseDriver (объект $db). Соответственно и методы update и updateObject. Я тут дня 2 не мог понять, куда метод потерялся. ;=)) Переписал код примера подробнее.
Обратите внимание, что нам не нужно экранировать имя таблицы; метод insertObject делает это за нас.
Метод insertObject выдаст ошибку, если возникнет проблема с вставкой записи в таблицу базы данных.
Если вы предоставляете уникальное значение первичного ключа (как в примере выше), настоятельно рекомендуется перед попыткой вставки выбрать из таблицы значение этого столбца.
Если вы просто вставляете следующую строку в вашу таблицу (т. Е. База данных генерирует значение первичного ключа), вы можете указать имя столбца первичного ключа в качестве третьего параметра метода insertObject (), и метод обновит объект с помощью вновь сгенерированного значения первичного ключа.
Например, с учетом следующего утверждения:
$result = $dbconnect->insertObject('#__my_table', $object, 'primary_key');
после выполнения $object->primary_key будет обновлено значением первичного ключа вновь вставленной строки.
ПОДСКАЗКА: Установите $object->primary_key в null или 0 (ноль) перед вставкой.
Как сохранить пустое значение как NULL при вставке объекта.
Если значение столбца по умолчанию равно NULL, вам не следует добавлять это имя столбца к объекту. Пусть система баз данных сохранит значение NULL в качестве значения по умолчанию. Если значение столбца по умолчанию не равно NULL и разрешено хранить нулевые значения, вы должны указать это в коде. Смотрите, как это сделать, в следующем примере.
// Создать и заполнить объект. $profile = new stdClass(); $profile->user_id = 1001; $profile->profile_key='custom.message'; $profile->ordering=1; /** Первый случай [значение по умолчанию - NULL] **/ // Столбец 'profile_value' имеет значение NULL в качестве // значения по умолчанию. Итак, мы не будем добавлять его // к объекту. Компонент database engine сохранит значение // NULL в качестве значения для столбца 'profile_value'. // $profile->profile_value='Вставка записи с помощью insertObject()'; /** Второй случай [строка в качестве значения по умолчанию, // и вы также можете сохранить нулевое значение] **/ // Столбец 'profile_value' имеет пустую строку " в качестве // значения по умолчанию, но мы также можем сохранить нулевое // значение. Итак, мы должны добавить имя столбца и нулевое // значение в качестве его значения. $profile->profile_value = $db->quote('NULL'); // Вставить объект в таблицу профиля пользователя. $result = JFactory::getDbo()->insertObject('#__user_profiles', $profile);
Обновление данных
Используя SQL
Класс JDatabaseQuery предоставляет два метода для обновления данных: update() и set().
// Получаем объект коннектора базы данных $db = JFactory::getDbo(); // Получаем объект запроса $query = $db->getQuery(true); // Поля для обновления $fields = array( $db->quoteName('profile_value') . ' = ' . $db->quote('Обновление данных для пользователя 42.'), $db->quoteName('ordering') . ' = 2' ); // Условия обновления $conditions = array( $db->quoteName('user_id') . ' = 42', $db->quoteName('profile_key') . ' = ' . $db->quote('custom.message') ); $query->update($db->quoteName('#__user_profiles')) ->set($fields) ->where($conditions); // Устанавливаем и выполняем запрос $db->setQuery($query) ->execute();
Используя объект
По аналогии с методом insertObject()
класс JDatabaseDriver предоставляет метод updateObject($table, &$object, $key, $nulls = false)
для обновления данных:
$table
– имя таблицы&$object
– объект, публичные свойства которого соответствуют полям в таблице$key
– первичный ключ$nulls
– передаемtrue
, если хотим обновитьNULL
значения
Ниже мы обновляем нашу таблицу, используя существующий первичный ключ id
:
// Создаем и заполняем объект $object = new stdClass(); $object->id = 1; // должен быть валидный первичный ключ $object->title = 'Моя запись'; $object->description = 'Запись, которая будет обновлена.'; $db = JFactory::getDbo(); // Обновляем данные, используя id в качестве первичного ключа $result = $db->updateObject('#__custom_table', $object, 'id');
Так же как и insertObject()
, метод updateObject()
автоматически экранирует данные: применяет quoteName()
к имени таблицы и колонкам, а также quote()
к значениям.
Метод возвращает true
, если обновление прошло успешно или не было найдено полей для обновления, в противном случае - выдаст ошибку RuntimeException
.
Мы должны убедиться, что запись уже существует, прежде чем пытаться обновить ее, поэтому мы, можем, добавить какую-то проверку записи перед выполнением метода updateObject.
Удаление данных
Удаление записи выполняется с помощью метода delete() класса JDatabaseQuery.
// Получаем объект коннектора базы данных $db = JFactory::getDbo(); // Получаем объект запроса $query = $db->getQuery(true); // Удаляем все custom-ключи пользователя 42 $conditions = array( $db->quoteName('user_id') . ' = 42', $db->quoteName('profile_key') . ' = ' . $db->quote('custom.%') ); $query->delete($db->quoteName('#__user_profiles')) ->where($conditions); // Устанавливаем и выполняем запрос $db->setQuery($query) ->execute();
Пример Кода модуля
Ниже приведен код простого модуля Joomla, который вы можете установить и запустить, чтобы продемонстрировать использование функциональности JDatabase для обновления записей в базе данных, и который вы можете адаптировать для экспериментов с некоторыми из концепций, описанных выше. Если вы не уверены в разработке и установке модуля Joomla, то вам поможет руководство по созданию простого модуля. Важное примечание: В любых расширениях Joomla, которые вы разрабатываете, вам следует избегать прямого доступа к основным таблицам Joomla подобным образом и вместо этого использовать API-интерфейсы Joomla, если это вообще возможно, потому что структуры базы данных могут измениться без предупреждения. В папке mod_db_update создайте следующие 2 файла:
mod_db_update.xml
<?xml version="1.0" encoding="utf-8"?> <extension type="module" version="3.1" client="site" method="upgrade"> <name>Database update demo</name> <version>1.0.1</version> <description>Code demonstrating use of Joomla Database class to perform SQL UPDATE statements</description> <files> <filename module="mod_db_update">mod_db_update.php</filename> </files> </extension>
mod_db_update.php
<?php defined('_JEXEC') or die('Restricted Access'); use Joomla\CMS\Factory; $db = Factory::getDbo(); $me = Factory::getUser(); if ($me->id == 0) { echo "Not logged on!"; } else { $email = $me->email; // измените регистр адреса электронной почты $email_uppercase = strtoupper($email); if ($email == $email_uppercase) { $new_email = strtolower($email); } else { $new_email = $email_uppercase; } $query = $db->getQuery(true); $fields = array($db->quoteName('email') . " = '{$new_email}'"); $conditions = array($db->quoteName('id') . ' = ' . $me->id); $query->update($db->quoteName('#__users'))->set($fields)->where($conditions); echo $db->replacePrefix((string) $query); $db->setQuery($query); if ($result = $db->execute()) { echo "Адрес электронной почты успешно изменен!"; } }
Приведенный выше код обновляет поле адреса электронной почты в записи пользователя текущего вошедшего в систему пользователя, переключаясь между верхним и нижним регистром при последовательных перезагрузках веб-страницы. Метод Factory::getUser() возвращает объект user текущего вошедшего в систему пользователя, или, если он не вошел в систему, то пустой объект user, поле id которого равно нулю. Выражение $db->replacePrefix((string) $query) возвращает фактическую инструкцию SQL, и вывод этого может быть полезен при отладке.
Заархивируйте каталог mod_db_update, чтобы создать mod_db_update.zip .
В вашем администраторе Joomla перейдите в раздел Установка расширений и через вкладку Загрузить файл пакета загрузите этот zip-файл, чтобы установить этот пример модуля журнала.
Сделайте этот модуль видимым, отредактировав его (нажмите на него на странице Модулей), затем:
- опубликование его статуса
- выбор позиции на странице для ее отображения
- на вкладке назначение меню укажите страницы, на которых оно должно отображаться
Когда вы посещаете веб-страницу сайта, вы должны увидеть модуль в выбранной вами позиции, и он должен вывести инструкцию SQL UPDATE и подтвердить, что он успешно обновил запись. Чтобы убедиться, что он правильно обновил запись, зайдите в phpmyadmin и просмотрите таблицу пользователей в базе данных Joomla. Обновления не отображаются с помощью функции admin Users на серверной части, так как Joomla отображает в нижнем регистре все адреса электронной почты в записях.