Уже закончен долгообещанная третья версия PHPixie ORM компонента. Он теперь полностью независим от фреймворка и может спокойно использоваться сам по себе. В связи с этим, пока продолжается работа над другими компонентами и пишется документация, разработчики составили небольшой туториал для того чтобы можно было уже начать работу с ОРМ. Ниже я предоставлю его перевод и добавлю несколько вещей от себя, но сначала давайте посмотрим чем полезным порадует нас эта версия:
Надеюсь я смог вас заинтересовать, теперь посмотрим на пример с ссылки вверху в переводе:
Попробовать этот пример у себя достаточно просто:
Эта ORM разрабатывалась больше года и нам очень интересны все ваши вопросы и замечания, очень ждем комментариев.
- Большинство ORM используют Model классы, которые используются как для выполнения запросов так и для репрезентации самых записей в базе данных. Например так делают Kohana и Laravel. PHPixie разделила модель на Repository, Entity и Query, каждая из которых имеет строго свое предназначение.
- Кроме SQL баз данных (SQLite, PostgreSQL, MySQL) полностью поддерживается также Mongo. Вы сможете связать отношениями модели с SQL баз данных с моделями хранящимися в коллекциях Mongo.
- Чтобы поддерживать связи между разными базами ( например между таблицами в разных базах в MySQL ) много ORM используют отдельные запросы вместо join-ов и субзапросов. PHPixie же использует субзапросы всегда где это возможно.
- Поддержка встроенных сущностей в Mongo
- На 97% покрыта юнит тестами ( планируется 100% до конца этой недели), и еще на 75% функционалными тестами.
- Эффективное использование Query позволяет уменьшить число запросов к базе. Например вам надо связать все топики автора с какими-то тегами. В большинстве ОРМ вам придется сначала найти топики, потом теги и тогда связать их ( 3 запроса к БД ). PHPixie позволяет сделать это за один запрос. Кстати пример этого есть в туториале снизу
Надеюсь я смог вас заинтересовать, теперь посмотрим на пример с ссылки вверху в переводе:
<?php
require_once('vendor/autoload.php');
$config = new \PHPixie\Config();
//Инициализация компонента базы данных
$database = new \PHPixie\Database($config->dataStorage(array(
'default' => array(
'driver' => 'pdo',
'connection' => 'sqlite::memory:'
)
)));
//И самой ОРМ
$orm = new \PHPixie\ORM($database, $config->dataStorage(array(
'relationships' => array(
array(
//У феи может быть много цветов
'type' => 'oneToMany',
'owner' => 'fairy',
'items' => 'flower'
)
)
)));
//Создание табличек
$connection = $database->get('default');
$connection->execute('
CREATE TABLE fairies (
id INTEGER PRIMARY KEY,
name VARCHAR(255)
)
');
$connection->execute('
CREATE TABLE flowers (
id INTEGER PRIMARY KEY,
name VARCHAR(255),
fairy_id INTEGER
)
');
//Моделей больше не существует
//Их заменяют Repositories, Entities и Query
/*
Мы все ненавидим когда сущности также являются запросами:
$fairy->name = 'Trixie';
$fairy->save();
$fairy->where('name', 'Stella')->find();
*/
//Репозитории создаются автоматически для существующих табличек
$fairyRepository = $orm->get('fairy');
$flowerRepository = $orm->get('flower');
//Это все была инициализация
//А теперь приступим
//Создадим несколько фей
$trixie = $fairyRepository->create();
$trixie->name = 'Trixie';
$trixie->save();
//Версия покороче
$fairyRepository
->create(array('name' => 'Stella'))
->save();
//А еще нам понадобятся цветки
foreach(array('Red', 'Yellow', 'Green', 'Purple') as $name) {
$flowerRepository
->create(array('name' => $name))
->save();
}
//А теперь создадим Query
//аналог WHERE `id` > 1 AND ( `name` = 'Green' OR `name` = 'Red')
$green = $flowerRepository->query()
->where('id', '>', 1)
->startAndWhereGroup()
->where('name', 'Green')
->or('name', 'Red')
->endGroup()
->findOne();
//или лаконичнее
$green = $flowerRepository->query()
->where('id', '>', 1)
->and(function($q){
$q
->where('name', 'Green')
->or('name', 'Red')
})
->findOne();
//Связи
//Каждая связь добавляет свойства в Сущности и Запросы
//В нашем случае свойство 'flowers' предоставляет методы add(), remove() и removeAll()
//Это намного удобнее чем методы addFlower(), removeFlower() и removeAllFlowers() на самом объекте
$trixie->flowers->add($green);
//При связывании объектов, значение кешируется сразу в обе стороны
//чтобы избежать дополнительных запросов к базе
//В даном случае это кажется на таким уж важным, так как добиться такого эффекта
//для oneToMany достаточно просто. Но для manyToMany оно тоже будет работать
assert($green->fairy() == $trixie);
//Теперь попробуем связать все цветы кроме Green c феей Stella
//И уложиться в один запрос
//Зададим запрос который нашел бы Стеллу
$stellaQuery = $fairyRepository->query()
->where('name', 'Stella');
//И запрос который найдет цветы
$allExceptGreen = $flowerRepository->query()
->whereNot('name', 'Green');
//И теперь магия
$stellaQuery->flowers->add($allExceptGreen);
//Также Query позволяет изменять сущности без выборки
//Например переименуем цветок Purple в Blue
$flowerRepository->query()
->where('name', 'Purple')
->update(array(
'name' => 'Blue'
));
//Можно найти фею у которой есть определенный цветок:
$trixie = $fairyRepository->query()
->relatedTo('flowers', $green)
->findOne();
//А теперь найдем всех фей у которых есть хотя бы один цветок
//И сразу подгрузим все их цветки
$fairies = $fairyRepository->query()
->relatedTo('flowers')
->find(array('flowers')); //так задается прелоудинг связей
//И выведем их как простые объекты
//Удобно для json_encode()
print_r($fairies->asArray(true));
//Больше примеров потом =)
Попробовать этот пример у себя достаточно просто:
git clone https://github.com/phpixie/orm
cd orm/examples
#если у вас еще нет Композера
curl -sS https://getcomposer.org/installer | php
php composer.phar install
php quickstart.php
Эта ORM разрабатывалась больше года и нам очень интересны все ваши вопросы и замечания, очень ждем комментариев.