Doctrine Collection Eager Loading

hell0w0rd

Продвинутый новичок
Парочка есть, но они не дотягивают даже до доктрины. Но от стремления к чистому коду и использования doctrine приложение становится более тормознутым, разработка также тормозит, потому что подобные вещи ORM должна уметь из коробки, а до сих пор не умеет. Хочешь доктрину - забей на eager loading, заткни редис во все дыры и радуйся красивому коду.
Я для себя взял nodejs и query-builder, сделал супер-быстрое rest-api и доволен как слон)
 

AmdY

Пью пиво
Команда форума
В первую доктрину UofW прикручивался в сотню строк кода. Хотя, имхо, фигня все эти рушечки, ради которых пришлось сломать ольшую часть функционала, а реально они нужны в 1% да и то с натягом.
 

stalxed

Новичок
Всё зависит от задачи.
Мне часто попадаются задачи, где нужно написать кастумную систему ERP, CRM.
По производительности сразу говорят, что готовы выделить несколько серверов для всего около 100 работников.
100 уников и несколько серверов.
Грех не использовать доктрину. Да и невозможно не использовать. Иначе никогда не закончишь писать код...

На высоконагруженный портал, я бы даже думать о доктрине не стал.
 

stalxed

Новичок
В первую доктрину UofW прикручивался в сотню строк кода. Хотя, имхо, фигня все эти рушечки, ради которых пришлось сломать ольшую часть функционала, а реально они нужны в 1% да и то с натягом.
Вы UoW называете рюшечкой?
Серьёзно, как можно после UoW смотреть во всяких YII, Laravel спокойно на ActiveRecordовскую $object->save();
Я не вижу недостатков UoW, по мне php doctrine 2 просто совершенство: оно просто дико логично работает.
 

MiksIr

miksir@home:~$
Эм... uow сравнивать/противопоставлять ar? Что-то мешает использовать ar+uow?
 

stalxed

Новичок
Под UoW в phpdoctrine2 я подразумеваю DataMapper+UoW+Entity Manager.
Суть в том, что php doctrine 2 единственный фреймворк в этой категории.
Бизнес логика сущности(Entity), кода выборки(Repository), изменения записи(Entity Manager) - разнесены очень классно.
 

Вурдалак

Продвинутый новичок
Интересные вы, с вопроса "как сделать eager loading в два запроса, вместо N*M" вы скатились к ответственности объектов. Да насрать на это всем, когда без дополнительных костылей доктрина делает 3000 запросов там, где можно было сделать 2.
Pull request, вот это всё, нет? Не всё же одни опечатки да выравнивания исправлять, да?

Ты не обобщай, кстати. Тебе насрать на качество кода — это не значит, что всем остальным тоже.
 

hell0w0rd

Продвинутый новичок
stalxed, в доктрине?))) логично?)) В доктрине EntityManager является GodObject, выполняющий все задачи)
Вурдалак, мне не насрать на качество кода. Вот только с доктриной приходится костылить, чтобы добиться того, что нужно.
Не всё же одни опечатки да выравнивания исправлять, да?
Кто еще обобщает)
 

Вурдалак

Продвинутый новичок
hell0w0rd, так почему бы это говно не запихнуть в одну папку, зачем из-за дерьмовой Doctrine гадить весь код? По твоей логике это нормально.

Инструмент может быть не очень хороший, местами кривой. Но почти всегда есть возможность его спрятать под капот. Инкапсуляция — это вам не в тапки срать, это не слово из ВУЗа, это реальная вещь, советую.
 
Последнее редактирование:

AmdY

Пью пиво
Команда форума
Под UoW в phpdoctrine2 я подразумеваю DataMapper+UoW+Entity Manager.
Суть в том, что php doctrine 2 единственный фреймворк в этой категории.
Бизнес логика сущности(Entity), кода выборки(Repository), изменения записи(Entity Manager) - разнесены очень классно.
Говорю же рюшечки, нет там ни реального DataMapper, фактически лишь тупой прямой биндинг в стиле AR, даже в YII2 он более мэпперестый, ни полноценного UoW разгребающего транзакцию. А EM в контексте однопоточного php и вовсе комичная фигня. Просто набор базззворд и обезьянки без понятия повторяющие заученные движения без пользы для проекта, а то и в минус.

Larovel-овское решение не мешает налепить того же, но только не знаю кому это нужно. Есть куча статей и про entity+repository и даже ddd наворачивают, а толку от этого -0.
 

Redjik

Джедай-мастер
коллега тут негодуэ
(17:05:20) *****: Я сегодня наступил на эпичный баг в доктрине.
(17:05:31) *****: У них там реализован UoW. Соответственно все объекты, за которыми надо следить находятся в неком массиве. Как ключ используется spl_object_hash(). Который не гарантирует уникальность, если объекты удалялись.
(17:05:50) *****: Короче у нас удалялся старый объект, создавался новый, но так как происходила коллизия доктрина считала, что он уже есть и не сохраняла его.

е@#ый Unit Of Work
 

Koc

Новичок
никогда на такое поведение UoW не наталкивались.

По сабжу у нас наподобие такого используется:

PHP:
<?php

class CompanyCategoryRepository extends EntityRepository
{
    public function loadCompanyCategoriesCollectionForCompany(Company $company)
    {
        $companyCategories = $this->_em->createQueryBuilder()
            ->select('cc')
            ->from('MetalCompaniesBundle:CompanyCategory', 'cc')
            ->join('cc.category', 'c')
            ->addSelect('c')
            ->orderBy('c.title')
            ->where('cc.company = :company')
            ->setParameter('company', $company)
            ->getQuery()
            ->getResult()
        ;

        $coll = $company->getCompanyCategories();
        foreach ($companyCategories as $companyCategory) { /* @var $coll \Doctrine\ORM\PersistentCollection */
            $coll->hydrateAdd($companyCategory);
        }
        $coll->setInitialized(true);
    }
}
я думаю, топикстартеру не составит труда написать подобный метод, который будет принимать Company[] (список объектов а не один конкретный объект)
 

AmdY

Пью пиво
Команда форума
Вурдалак, ты посмотри на ответ Koc и скажи кто здесь употребляет. Просто у людей проблемы со здравым смыслом и уже задолбало в легаси из лазанья кода копаться, лучше уж линейные спагетти.
 

stalxed

Новичок
stalxed, в доктрине?))) логично?)) В доктрине EntityManager является GodObject, выполняющий все задачи)
Вурдалак, мне не насрать на качество кода. Вот только с доктриной приходится костылить, чтобы добиться того, что нужно.

Кто еще обобщает)
Приведу пример проекта(НЕ МОЙ), который лично я могу сказать, что успешно выполнен на php doctrine.
Скажу честно, это лучший проект, что я видел в плане качества кода при столь огромном количестве.

https://github.com/orocrm/platform Платформа
https://github.com/orocrm/crm CRM на базе Платформы

В плане php doctrine они сделали очень классную систему datagrid:
1) Код описывается в yml, пример https://github.com/orocrm/crm/blob/master/src/OroCRM/Bundle/CaseBundle/Resources/config/datagrid.yml
2) Этот конфиг превращается в массив при сборке контейнера сервисов.
3) Этот код строит DQL запрос. Обычно используются массивы. В теории можно использовать коллекцию объектов.

Ещё у них есть графический редактор сущностей(Doctrine Entity), т.е. к любой php doctrine сущности вы можете добавить поля разных типов в графическом режиме! Более того, также можно добавлять новые сущности(Doctrine Entity) в графическом режиме!

Понятия не имею, как это реализовано(пока нет необходимости в данном функционале), но работает эту штука замечательно.

В остальном всё используется стандартно в плане доктрины.

То, что система легкая и простая не повернётся сказать язык. Но всё летает! Никаких проблем производительности нет.
Никакого говно кода не вижу. Код стремится к идеальности(да, есть мелкие шероховатости, но куда без них).

Я сейчас строю на их платформе кастумную CRM.
CRM - это обозначает море данных, форм, коллекций, сново данных, форм.... и так по кругу.

И всё зашибись! Велосипеды не пишу, на баги доктрины не попадаю.
Были проблемы только по типу "сам дурак, читай документацию внимательнее".

P.S. Если разработчики ORO есть на форуме огромная вам благодарность за такой чудесный движок!
P.S.S.: Как правильно перевести на русский Doctrine Entity?
 
Последнее редактирование:
  • Like
Реакции: AmdY

hell0w0rd

Продвинутый новичок
stalxed, Я искренне считаю, что лучше взять это море логики и вынести на фронтенд. А в бэкенде написать простое api и радоваться. Ну и я не вижу поводов восхищаться этим конфигом. Вынос sql/php/js/другой_язык в конфиги - зло.
 

stalxed

Новичок
Это не конфиг, это новый компилируемый язык.
Они изобрели над php doctrine ещё один компилируемый язык для самой сложной задачи - для datagrid.
Что в этом плохого?
Я вначале тоже ужаснулся, а потом понял, что чёрт возьми, весьма большая часть сложного кода php doctrine, который приходилось писать, ушла прочь.
Работает быстро.
Язык, который они тут изобрели - простой.
Пытаюсь найти в этом ложку дёгтя, а её нет.
Хотя есть, наследование слабое, я написал несколько расширений.
Дак это, и расширения пишутся легко и непринужденно.
Нарушений принципов ООП лично я в этом не вижу.

Данный конфиг и превращается в API метод.
Т.е. есть API метод, он берёт из запроса название data-grid.
Считывает конфиг, генерит JSON ответ.
 

AmdY

Пью пиво
Команда форума
stalxed, вот оно, щах и мат. Извини, даже не думал что ты окажешься одним из того мифического 1%. Если ты делаешь коробку, которую будут расширять другие, когда нужно заботиться о обратной совместимости и возможности безопасного апгрейда ядра, то это всё не помешает.

Кстати, про конфиги, замени их php массивом с замыканиями возвращающие биллдер и получишь большую выразительность + 100500 к расширябельности, yml очень неудачный выбор. Хотя подобная система легко пищется без симфони и доктрины, на том же laravel есть http://administrator.frozennode.com/docs/model-configuration#examples , он гораздо проще, так как является потомком версии писанной ещё во времена 3-й версии, но как демонстрация отсутствия ограничений вполне себе.
 

stalxed

Новичок
Если ты делаешь коробку, которую будут расширять другие, когда нужно заботиться о обратной совместимости и возможности безопасного апгрейда ядра, то это всё не помешает..
При любой разработке у меня до 40-60 процентов времени уходит на расширения существующей системы.
Чтобы код основной бизнес логики был проще.
В большинстве случаев эти расширения не нужны в будущем. Только для одного проекта. И в этом нет ничего страшного!
Постоянно кричат, убирайте дублирующий код. Раньше это было банально - создал функцию с дублирующим кодом. Продумал параметры.
Вот вам и рефакторинг.
Но многие на этом уровне и остановились.
Это подход процедурного программирования. Т.е. многие сейчас пишут на ООП фреймворках процедурным стилем.
Я же считаю, что расширение фреймворка под свою задачу - является рефакторингом. И является реальным ООП.

Например, если автору темы так нужно загружать коллекции коллекций - то написать Custom Walker наверное займёт меньше времени, чем отнял этот холивар.

Но я думаю, за что меня тут уже заклевали, что объекты вовсе не нужны.
Какая одна из главных фишек twig? Он писался явно с учётом программирования с php doctrine.
Без разницы вернёт вам доктрина коллекцию объектов или ассоциированный массив - в twig обращение и к тому и к тому одинаково.
Что будет, если в примере выше мы добавим для телефона поле description типа текст, и не перепишем все запросы подобного вида(коллекция клиентов, в каждом клиенте коллекция объектов телефонов)?
100 клиентов * 100 телефонов * 64 K(обычное текстовое поле) = 640 000 кб = 640 МБ озу
В объектах телефон - нужно, скорее всего при выборке коллекции клиентов - только поле телефон. Зачем грузить множество объектов телефонов? Это попросту может стать опасным.

Кстати, про конфиги, замени их php массивом с замыканиями возвращающие биллдер и получишь большую выразительность + 100500 к расширябельности, yml очень неудачный выбор. Хотя подобная система легко пищется без симфони и доктрины, на том же laravel есть http://administrator.frozennode.com/docs/model-configuration#examples , он гораздо проще, так как является потомком версии писанной ещё во времена 3-й версии, но как демонстрация отсутствия ограничений вполне себе.
Откровенно говоря, я не вижу разницы между конфигом на xml, yml, php.
По поводу расширяемости - эту проблему решают Event Listener`ы.
Зато сам конфигурационный файл остаётся простым.
Т.е. логика делится на простую бизнес логику в конфиге и дополнительную магию в Event Listener.
И подобные конфиги, повторю, можно назвать компилируемыми языками. Поэтому не критично в каком виде они будут php, xml, yml, txt.
 
Сверху