Объектно-реляционные картографы (ORM) — это круто. Они помогают вам быстро создавать приложение, не беспокоясь о написании необработанных SQL-запросов. Идея состоит в том, чтобы упростить взаимодействие с базой данных и избежать возможных ошибок при написании сложных запросов. Фактически, современные ORM могут генерировать модели / объекты из базы данных, и наоборот.
Но реальность работы с любым ORM заключается в том, что использовать его просто, только если у вас уже есть опыт его использования. Чтобы извлечь максимальную пользу из этого, вы должны иметь глубокое понимание концепций. И есть крутая кривая обучения, связанная с любым ORM.
Если все, что вы разрабатываете, — это простое приложение с несколькими таблицами, то использование полноценного ORM, вероятно, является излишним. В этом случае вы можете рассмотреть возможность использования NotORM. NotORM легок в освоении и прост в использовании, поскольку предоставляет интуитивно понятный API для взаимодействия с базой данных. В этой статье я научу вас, как использовать NotORM.
Прежде чем мы начнем, вот схема базы данных, которую я буду использовать на протяжении всей статьи.
Таблица: автор + ---- + ------------------------ + | id | имя | + ---- + ------------------------ + | 1 | Халил Джебран | | 2 | Сэр Артур Конан Дойл | | 3 | Пауло Коэльо | + ---- + ------------------------ + Стол: книга + ---- + ----------------- + ----------- + | id | название | author_id | + ---- + ----------------- + ----------- + | 1 | Пророк | 1 | | 3 | Шерлок Холмс | 2 | | 4 | Алхимик | 3 | + ---- + ----------------- + ----------- + Таблица: категория + ---- + ------------ + | id | категория | + ---- + ------------ + | 1 | стихотворение | | 2 | статья | | 3 | учебные пособия | | 4 | философия | | 5 | очерки | | 6 | история | + ---- + ------------ + Таблица: book_category + ---- + --------- + ------------- + | id | book_id | category_id | + ---- + --------- + ------------- + | 1 | 1 | 4 | | 3 | 3 | 6 | | 4 | 4 | 4 | + ---- + --------- + ------------- +
Подключение к базе данных
Первым шагом к использованию NotORM является создание экземпляра объекта NotORM
который использует активное соединение PDO для взаимодействия с базой данных.
<?php $dsn = "mysql:dbname=library;host=127.0.0.1"; $pdo = new PDO($dsn, "dbuser", "dbpassword"); $library = new NotORM($pdo);
Имя источника данных (DSN) является распространенным способом описания соединения с базой данных. Он содержит имя используемого драйвера базы данных, имя базы данных и адрес хоста. Конструктор PDO принимает DSN и имя пользователя базы данных и пароль для подключения. После подключения объект PDO передается в NotORM. Мы будем использовать этот экземпляр NotORM в этой статье.
Базовый поиск
Теперь, когда мы подключены через NotORM, давайте перечислим все книги в базе данных.
<?php $books = $library->book(); foreach ($books as $book) { echo $book["id"] . " " . $book["title"] . "<br>"; }
Результат:
1 Пророк 3 Шерлок Холмс 4 Алхимик
Это так просто! $library
— это объект NotORM, а book
— это имя таблицы, в которой хранится информация о нашей книге. Метод book()
возвращает многомерный массив с столбцом первичного ключа таблицы в качестве индекса первого уровня. В пределах foreach
$book
— это представление одной записи книги, массива с ключами, названными в честь имен столбцов таблицы. $book["title"]
возвращает значение из столбца title для этой записи.
В большинстве случаев вам не нужно извлекать все столбцы из таблицы. Вы можете указать только интересующие вас столбцы с помощью метода select()
. Например, если вам нужен только заголовок, вы можете переписать пример следующим образом:
<?php $books = $library->book()->select("title"); foreach ($books as $book) { echo $book["title"] . "<br>"; }
Получение определенных столбцов особенно желательно для таблиц с большим количеством столбцов, поэтому вам не нужно тратить время и память на поиск и сохранение значений, которые вы не будете использовать.
Чтобы извлечь одну запись из таблицы, используя ее первичный ключ, мы ссылаемся на первичный ключ в предложении WHERE
запроса при написании SQL. В NotORM есть много способов выполнить задачу; Самый простой способ — использовать первичный ключ в качестве индекса свойства таблицы.
<?php $book = $library->book[1]; echo $book["title"];
Это просто извлечет информацию о книге из записи с идентификатором 1.
Фильтрация по значениям столбцов
NotORM позволяет фильтровать результаты по условиям, которые будут указаны в WHERE
запроса с использованием метода where()
. Чтобы проиллюстрировать это, давайте поищем в таблице книги с названием «Алхимик».
<?php $books = $library->book->where("title LIKE ?", "%Alchemist%"); foreach ($books as $book) { echo $book["id"] . " " . $book["title"] . "<br>"; }
Результат:
4 Алхимик
Если вы не знакомы с подготовленными утверждениями, вам может быть интересно, что означает этот знак вопроса. Это способ привязки параметров к запросам, выполняемым PDO, так что вы можете выполнить один и тот же запрос много раз, просто изменив значения. Вопросительный знак или переменная типа :title
действует как заполнитель значений. Вы можете прочитать больше о подготовленных заявлениях PDO в руководстве по PHP.
NotORM также позволяет связывать методы where()
для применения более чем одного условия.
<?php $books = $library->book->where("title LIKE ?", "%The%") ->where("id < ?", 5); foreach ($books as $book) { echo $book["id"] . " " . $book["title"] . "<br>"; }
1 Пророк 4 Алхимик
Оператор, выданный NotORM для приведенного выше примера, эквивалентен следующему запросу SQL:
SELECT * FROM book WHERE title LIKE "%The%" AND id < 5
Сортировка результатов
Скорее всего, у вас будут прямые запросы с одной таблицей во всем приложении. В реальных приложениях вам необходимо объединить множество таблиц, упорядочить записи на основе значений в разных столбцах, ограничить количество извлекаемых записей и т. Д.
Вы можете упорядочить результаты по одному или нескольким столбцам в порядке возрастания или убывания. Приведенный ниже пример вернет книги в порядке убывания их идентификаторов.
<?php $books = $library->book->order("id desc"); foreach ($books as $id => $book) { echo $id . " " . $book["title"] . "<br>"; }
4 Алхимик 3 Шерлок Холмс 1 Пророк
Если вы хотите упорядочить результаты по нескольким столбцам, вы можете указать их через запятую.
<?php $books = $library->book->order("id desc, title asc"); foreach ($books as $id => $book) { echo $id . " " . $book["title"] . "<br>"; }
Полученные записи будут возвращены в порядке убывания их идентификатора, и если существует более одной записи с одинаковым идентификатором (конечно, не будет), она будет в порядке возрастания заголовка.
NotORM также поддерживает ограничение результатов. Давайте ограничим набор результатов двумя записями, начиная со смещения 0:
<?php $books = $library->book->limit(2, 0); foreach ($books as $id => $book) { echo $id . " " . $book["title"] . "<br>"; }
1 Пророк 3 Шерлок Холмс
Столы
До сих пор мы обсуждали списки книг или заставляли НОРМ работать только с одним столом. Теперь мы хотим двигаться дальше, например, выяснить, кто является автором книги и так далее.
Попробуем перечислить книги вместе с их авторами. В нашей библиотечной базе данных таблица книг имеет внешний ключ author_id
который ссылается на таблицу author
(каждая книга может иметь только одного автора в этой настройке).
<table> <tr><th>Book</th><th>Author</th></tr> <?php $books = $library->book(); foreach ($books as $book) { echo "<tr>"; echo "<td>" . $book["title"] . "</td>"; echo "<td>" . $book->author["name"] . "</td>"; echo "</tr>"; } ?> </table>
Вывод вышеуказанного кода:
Автор книги Пророк Халил Джебран Шерлок Холмс сэр Артур Конан Дойл Алхимик Пауло Коэльо
Когда вы вызываете $book->author["name"]
, NotORM автоматически связывает таблицу book
таблицей author
используя столбец author_id
и получает сведения об авторе для записи книги. Это случай отношения один-к-одному (запись в родительской таблице будет связана только с одной записью в дочерней таблице).
В случае отношений «один ко многим» вторичная таблица будет иметь более одной записи, соответствующей одной строке первичной таблицы. Например, предположим, что мы можем написать рецензии на книгу, поэтому для каждой книги будет ноль или более рецензий, которые хранятся в другой таблице. Тогда для каждой книги вам понадобится еще один цикл для отображения рецензий, если таковые имеются.
Для связи «многие ко многим» будет третья таблица, связывающая первичные и вторичные таблицы. У нас есть таблица категорий, в которой можно хранить категории книг, и книга может иметь ноль или более категорий, связанных с ней. Ссылка поддерживается с использованием таблицы book_category
.
<table> <tr><th>Book</th><th>Author</th><th>Categories</th></tr> <?php foreach ($books as $book) { echo "<tr>"; echo "<td>" . $book["title"] . "</td>"; echo "<td>" . $book["author"] . "</td>"; // book_category table joins book and category $categories = array(); foreach ($book->book_category() as $book_category) { $categories[] = $book_category->category["category"]; } echo "<td>" . join(", ", $categories) . "</td>"; echo "</tr>"; } ?> </tr> </table>
Автор книги Категории Пророк Халил Джебран Философия Шерлок Холмс Сэр Артур Конан Дойл Алхимик Пауло Коэльо философия, история
Когда вы вызываете метод book_category()
, он получает записи из таблицы book_category
, которая, в свою очередь, подключается к таблице category
с помощью $book_category->category["category"]
.
Существуют некоторые соглашения по умолчанию для имен таблиц и столбцов, которые, если вы будете следовать, могут упростить работу со связями таблиц в NotORM.
- Имя таблицы должно быть в единственном числе, то есть использовать книгу для названия таблицы, чтобы хранить детали книги.
- Используйте id в качестве первичного ключа для ваших таблиц. Не обязательно иметь первичные ключи для всех таблиц, но это хорошая идея.
- Внешние ключи в таблице должны называться table_id .
Как я уже сказал, это только соглашения по умолчанию. Вы можете следовать другим соглашениям, если хотите, но тогда вам нужно сообщить NotORM о соглашениях, которым они должны следовать. В библиотеке есть класс NotORM_Structure_Convention
для определения соглашения об именах. Вот простой пример использования, который я скопировал с сайта NotORM.
<?php $structure = new NotORM_Structure_Convention( $primary = "id_%s", // id_$table $foreign = "id_%s", // id_$table $table = "%ss", // {$table}s $prefix = "wp_" // wp_$table ); $db = new NotORM($pdo, $structure);
В этом примере все имена таблиц изменяются на множественное число с префиксом «wp_». Первичный ключ и внешние ключи были изменены на id_table .
Постоянство данных
До сих пор мы обсуждали получение данных, которые уже есть в базе данных. Далее нам нужно взглянуть на хранение и обновление данных.
Вставки и обновления довольно просты и понятны. Вам нужно только создать ассоциативный массив с именами столбцов в качестве ключей и передать его в качестве аргумента методу insert()
или update()
таблицы.
<?php $book = $library->book(); $data = array( "title" => "Beginning PHP 5.3", "author_id" => 88 ); $result = $book->insert($data);
insert()
вернет запись, если вставка прошла успешно, или false, если она не удалась. Оттуда вы можете получить идентификатор вставленной записи, используя $result["id"]
.
Чтобы обновить книгу, извлеките запись из базы данных, используя ее первичный ключ, а затем передайте значения, которые должны быть обновлены, в виде массива для update()
.
<?php $book = $library->book[1]; if ($book) { $data = array( "title" => "Pro PHP Patterns, Frameworks, Testing and More" ); $result = $book->update($data); }
update()
вернет true в случае успеха или false в случае сбоя обновления.
Точно так же вы можете удалить книгу, вызвав delete()
для объекта книги.
<?php $book = $library->book[10]; if ($book && $book->delete()) { echo "Book deleted successfully."; }
Важно помнить, когда вы обновляете или удаляете строку, сначала убедитесь, что она существует в базе данных, иначе ваш скрипт выдаст фатальную ошибку.
Резюме
Благодаря этой статье вы познакомитесь с простой библиотекой для взаимодействия с вашей базой данных. Реальность такова, что по мере роста вашего приложения код, использующий NotORM, станет менее управляемым, и вам придется решать, подходит ли NotORM, исходя из ожидаемого размера вашего приложения и других факторов. Но при использовании NotORM вам не нужно беспокоиться о написании необработанных SQL-запросов или создании классов сущностей со сложными отношениями. Скорее, вы можете использовать знакомую объектно-ориентированную нотацию для непосредственного обращения с таблицами и столбцами.
Изображение через Fotolia