...

пятница, 6 марта 2015 г.

PHPixie 3.0 ORM или новый взгяд на ActiveRecord

image Уже закончен долгообещанная третья версия PHPixie 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 http://ift.tt/1aO0DX9
cd orm/examples

#если у вас еще нет Композера
curl -sS http://ift.tt/SI3ujS | php

php composer.phar install
php quickstart.php


Эта ORM разрабатывалась больше года и нам очень интересны все вашы вопросы и замечания, очень ждем комментариев. А если вам интересно узнать о будущих компонентах и самом фреймворке то не забудьте подписаться на твиттер @phpixie


This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий