Как я и обещал, в этом уроке мы рассмотрим построение связей между таблицами, используя ORM. Поскольку материала получилось как-то очень много, решил разбить урок на две части.
Итак, думаю все помнят, что связи бывают четырех типов: связь «один-к-одному», связь «один-ко-многим», связь «много к одному» и связь «многие-ко-многим». Напомню для тех, кто забыл.
Связь один-к-одному — когда одной записи в таблице соответствует только одна запись в другой таблице. Допустим, если у нас есть таблица с фамилиями студентов и таблица с номерами зачетных книжек, то связь между ними будет один-к-одному, так как у одного человека может быть только одна зачетка (в пределах ВУЗ-а конечно). Впрочем, у меня было две зачетки, когда я, уже занимаясь написанием диплома по одной специальности, пошел на другую, но мы этот момент здесь не учитываем.
Связь один-ко-многим — когда одной записи в таблице соответствует несколько записей в другой таблице. Приведу уже набивший оскомину пример, как книги и авторы. Мы не рассматриваем книги, написанные несколькими авторами, поэтому в данном случае одному автору может соответствовать несколько книг, но книге — только один автор.
Связь много-к-одному — все аналогично рассмотренной выше записи один-ко-многим. Много книг, но у них один автор.
Связь много-ко-многим — когда нескольким записям в таблице соответствует несколько записей в другой таблице. Наглядный и часто используемый на сайтах пример — фильмы и жанры. Одному жанру может соответствовать несколько фильмов (фантастика — Прометей, Живая сталь, Вспомнить все итд). Но фильмы также могут быть нескольких жанров: (8 первых свиданий — это и комедия, и мелодрама одновременно).
Один к одному
Если брать наш пример, то у нас будет две таблицы — со списком студентов и со списком зачеток. В уроке Введение в ORM мы уже рассматривали некоторые правила по именованию полей в таблице. Согласно этим правилам первичный ключ будет называться id, а внешний ключ — название связанной таблицы в единственном числе + _id. То есть примерно так:
А модели будут такими:
class Model_Student extends ORM { protected $_has_one = array( 'book' => array( 'model' => 'book', 'foreign_key' => 'student_id', ), ); }
class Model_Book extends ORM { }
Как можно заметить, в классе Model_Student указывается название модели, отвечающей за связанную таблицу (в нашем случае это модель для таблицы зачеток book), а также название внешнего ключа student_id. Кстати, $_has_one переводится как «имеет один» или «есть один», так что если вы хоть немного знаете английский, запомнить этот и другие параметры (для других типов связей) будет несложно.
Получение
$student = ORM::factory('student', 2); echo $student->name; // Гриша Петров echo $student->book->number; // 14
Запросы, которые при этом будут выполнены, выглядят следуюшим образом:
SELECT `student`.* FROM `students` AS `student` WHERE `student`.`id` = 2 LIMIT 1 SELECT `book`.* FROM `books` AS `book` WHERE `book`.`student_id` = '2' LIMIT 1
Но для нас все это весьма прозрачно. Мы и знать не знаем ни про какие запросы. Мы просто создаем объекты и получаем нужные нам свойства. В этом вся прелесть ORM. Но если очень нужно, то запросы, которые генерирует ORM, вы всегда можете посмотреть с помощью такой вот строки:
echo View::factory('profiler/stats');
Хотя бы, чтобы проверить, сильно ли они тяжелые.
Много к одному
Опять берем приведенный выше пример — много книг написаны одним автором. Как и в прошлом примере у нас будет две таблицы — список книг и список авторов:
Модели:
Class Model_Book extends ORM { protected $_belongs_to = array( 'author' => array( 'model' => 'author', 'foreign_key' => 'author_id', ) ); };
class Model_Author extends ORM { }
Практически тоже самое, что и при связи «один-к-одному», только вместо $_has_one мы видим $_belongs_to, т.е. «принадлежит к».
Получение данных:
$book = ORM::factory('book', 3); echo $book->name; // Разум на торги echo $book->author->id; // 1 echo $book->author->name; // Андре Нортон
Запросы, которые будут выполнены:
SELECT `book`.* FROM `books` AS `book` WHERE `book`.`id` = 3 LIMIT 1 SELECT `author`.* FROM `authors` AS `author` WHERE `author`.`id` = '1' LIMIT 1
Продолжение следует.
<< Назад | Вперед >> |
Пожалуйста, зарегистрируйтесь для комментирования.
добрый день! пожалуйста подскажите как связать в ORM несколько баз, для нескольких поисковиков. заранее спасибо.
Вам наверное это надо:
В случае, если для работы Модели нужно использовать не стандартную БД, а какую-то другую, достаточно указать ее название:
Отсюда: http://kohanaframework.su/database/orm_entering
не, он наверно имел ввиду такое
db1.peoples(idpeople,people,….)
db2.flats(idflat,flat,address,.. , fk_db1_idpeople)
таблица связана с таблицей в другой базе данных.
если надо нечто, что не существует — обычно в СУБД есть инструменты для создания этого…в sql server знаю чтоно, для такого случая, можно создать типо мнимую бд, которая будет состоять из таблиц других баз — ток при этом все внешние ключи и прочая бабуйня не возможны. только тригерами или хранимыми процедурами самим реализовывать логику связи между таблицами
подозреваю что в орм этого нету, того через субд…там надо заставить работать с таблицами из разных бд
Спасибо за статьи! Все очень доступно описано. Освоил kohana за неделю благодаря вам )