Приветствую всех!
Сегодня я хочу рассказать о небольшой ORM библиотеке под названием RedBean с которой я на днях экспериментировал.
Прежде всего, пару слов о ORM (англ. Object-relational mapping, русск. Объектно-реляционная проекция) вообще.
Основное назначение таких библиотек – преобразование объектов, которые используются в программах, в записи реляционных баз данных и обратно.
Дело в том, что все данные в БД хранятся в таблицах (аналог двумерных массивов), а объекты могут быть организованы в сложные иерархии (например, объект типа «Post» может содержать массив объектов типа «Comment»). И для того, чтобы сохранить такую структуру в БД нужно использовать несколько таблиц с дополнительными полями, которые устанавливают связи между записями.
Все это увеличивает сложность SQL запросов и время разработки.
ORM библиотеки могут в таких ситуациях значительно упрощают жизнь разработчику. Но, естественно, за все нужно платить. В данном случае счет вы получите в виде повышенного потребления ресурсов.
Вернемся к RedBean.
Проиллюстрировать работу любой библиотеки проще всего на примере. Поэтому я написал небольшой скрипт.
<?php include 'oodb.php'; //подключаемся к БД RedBean_Setup::kickstartDev('Post,Comment','mysql:host=localhost;dbname=my_database', 'user_name', 'password'); $post = new Post(); $post->title = 'Новая запись'; $post->content = 'Просто какой-то текст'; $id = $post->save(); $comment = new Comment; $comment->author = 'admin'; $comment->text = 'Очень простой комментарий'; $comment->belongsTo($post); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="language" content="en" /> <title>Test RedBean</title> </head> <body> <ul> <?php $posts = Post::listAll(); foreach ($posts as $post) { $curPost = new Post($post['id']); echo '<li><strong>'.$curPost->getTitle().'</strong><br />'; echo $curPost->getContent(); $comments = $curPost->getRelatedComment(); echo '<ol>'; foreach ($comments as $comment) { echo '<li>'.$comment->text.' ('.$comment->author.')</li>'; } echo '</ol></li>'; } ?> </ul></body> </html>
Посмотрим, что он делает.
1) Подключаем библиотеку (строка 2). Тут объяснять нечего, RedBean состоит всего из одного файла.
2) Подключаемся к базе данных и создаем объекты, которые будем в ней хранить (строка 5).
Обе операции выполняются с помощью метода kickstartDev
. В первом параметре мы указываем перечень нужных объектов (они будут создаваться динамически). В остальных параметрах – данные, необходимые для подключения к базе (dns, имя пользователя и пароль).
Предварительно от нас требуется только создать пустую БД. Созданием таблиц, сохранением и чтением данных будет заниматься RedBean.
Примечание. Метод kickstartDev
переводит библиотеку в т.н. fluid режим. При этом если вы измените, количество или названия свойств объектов, то RedBean автоматически изменит структуру таблиц в БД. Этот режим имеет смысл использовать во время разработки. После переноса приложения на «боевой» сервер kickstartDev
лучше заменить на kickstartFrozen
. Библиотека перейдет во frozen режим, при этом таблицы автоматически изменяться не будут, но и потребление ресурсов сократится.
3) Создаем данные и сохраняем их в БД (строки 7-15).
В данном случае создано два объекта типов Post
и Comment
, каждый из которых содержит несколько свойств.
Обратите внимание, что свойства создаются автоматически. От нас требуется указать только название свойства и его значение.
Мы просто присваиваем значения нужным свойствам и вызываем метод save()
, который записывает объект в БД (строка 10).
Объект Comment
принадлежит Post
. Эту связь мы устанавливаем с помощью метода belongsTo
. При этом использовать save не нужно. Сохранение в БД произойдет автоматически.
4) Читаем данные из базы (строки 29-40).
Тут тоже все достаточно прозрачно. С помощью статического метода listAll
мы получаем массив со всеми объектами типа Post
, находящимися в БД.
Чтобы получить доступ к комментариям мы создаем объект типа Post
(строка 31) и при этом в качестве параметра указываем id
.
После этого мы можем использовать метод getRelatedComment
для получения массива с комментариями.
Примечание. Название метода getRelatedComment
формируется следующим образом. К приставке getRelated
добавляется имя объекта, который мы хотим получить.
Затем в цикле мы выводим комментарии.
В результате выполнения скрипта вы увидите такую страницу.
Теперь посмотрим, что у нас делается с базой данных.
Прежде всего, взгляните на перечень таблиц.
Как видите, RedBean создал 6 таблиц. Три из них (post, comment_post и comment) используются для хранения данных приложения, остальные – используются самой RedBean.
Теперь посмотрим, что сохранено в самих таблицах.
post
comment_post
comment
Думаю, вы уже догадались, в чем дело.
Между объектами Post и Comment отношение типа ОДИН-К-МНОГИМ и для его реализации не нужна промежуточная таблица. Т.е. если бы база создавалась вручную, мы бы обошлись всего двумя таблицами. Соответственно, упрощаются и SQL запросы.
Использовать или не использовать?
Это вопрос философский 🙂 . RedBean не единственная ORM библиотека. Например, существуют более мощные Propel и Doctrine.
Ответ будет зависеть от требований к конкретному приложению. В общем случае при использовании ORM увеличивается скорость разработки и упрощается поддержка, но при этом растет потребление ресурсов.
К тому же стоит учесть время, необходимое на изучение библиотеки. В этом RedBean значительно превосходит библиотеки типа Doctrine. Вряд ли у вас уйдет больше пары дней на эксперименты с RedBean.
В общем, думаю, что в ряде случаев использование RedBean будет вполне оправданно.
В заключение хочу сказать, что это статью нельзя рассматривать как руководство по использованию библиотеки. Поэтому я очень рекомендую вам почитать документацию на сайте.