Доктрина со статическими сущностями

У меня есть база данных, в которой я храню некоторые фиксированные значения, например категории продуктов. Когда я создаю новый продукт и хочу присвоить ему категорию, я делаю это следующим образом:

$categories = new ProductCategoryRepository();
$category = $categories->find(ProductCategory::EXAMPLE);

$product = new Product();
$product->setCategory($category);

Однако я не уверен, почему мне нужно все время искать в базе данных, чтобы получить статические объекты, о которых мое приложение уже знает.

Достаточно присвоить категорию статически. Может быть, примерно так:

$category = ProductCategory::EXAMPLE;

Теперь Doctrine должна сохранять связь с правильным идентификатором (описанным классом ProductCategory (который может быть сущностью?)), И мне больше не нужно искать в базе данных статические свойства.

Я пока не знаю, как это сделать. Я мог бы создавать новые сущности все время, но это не кажется правильным, потому что значения уже хранятся в БД, и они всегда одинаковы, а нет - новые сущности.

$category = new ProductCategory::EXAMPLE;

Однако получение отношения из продукта должно возвращать свойство как сущность:

$category = $product->getCategory();

return $category instanceof ProductCategory; // true

Есть ли способ добиться такого поведения?

Это больше вопрос архитектуры, чем настройка производительности. Я не хочу описывать информацию несколько раз (записи в базе данных, константы php, отношения сущностей и т. д.).

Слой Doctrine ORM имеет дело с объектами, поэтому я думаю, что вы в значительной степени застряли с использованием объектов категорий. Однако существует метод EntityManager :: getReference ('ProductCategory', $ id), который возвращает объект ссылочной категории, содержащий только идентификатор. Таким образом, сокращается объем передаваемых данных. docs.doctrine-project.org/projects/doctrine-orm/en/latest/…

Cerad 14.03.2018 17:04
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
1
709
2

Ответы 2

Если вы не хотите, чтобы он попадал в базу данных каждый раз, вы можете просто сохранить его в кэше:

public function getCategory(){
    return Cache::rememberForever('category-'.$this->category_id, function() {
        return $categories->find($this->category_id);
    });
}

Это извлечет информацию из базы данных, если она никогда не была извлечена, но просто извлечет ее из кеша, если это было. Вам придется использовать Cache::forget('category-2'), чтобы удалить его, или php artisan cache:clear. Ваши статические значения будут просто целочисленными идентификаторами, и ваши продукты будут иметь category_id, но сами категории будут кэшироваться.

Вы действительно пробовали это с объектами Doctrine? Обычно сущностями должен «управлять» менеджер сущностей. Ссылки хранятся во внутренней единице рабочего объекта. Создание существующего объекта вне менеджера сущностей редко заканчивается хорошо. Хотя, возможно, Laravel каким-то образом с этим справляется.

Cerad 14.03.2018 17:02

по общему признанию, я не знаю об этом, но я знаю, что кеш Laravel поддерживает кеширование объектов и обрабатывает сериализацию.

Jeff 14.03.2018 17:05

В Doctrine есть что-то, называемое «кешем второго уровня», но эта функция считается экспериментальной, и вам, возможно, следует внимательно прочитать документацию перед ее использованием. Цитата из официальная документация этой функции:

The Second Level Cache

The second level cache functionality is marked as experimental for now. It is a very complex feature and we cannot guarantee yet that it works stable in all cases.

Определение кэша сущностей выполняется следующим образом: (документация)

/**
 * @Entity
 * @Cache(usage = "READ_ONLY", region = "my_entity_region")
 */

Чтобы повысить производительность таких сущностей, о которых вы говорите в своем вопросе, вам также следует подумать о том, чтобы пометить их как «только для чтения», что приведет к увеличению производительности по сравнению с Doctrine 2.1, как можно найти в документация Doctrine по повышению производительности:

Read-Only Entities

Starting with Doctrine 2.1 you can mark entities as read only (See metadata mapping references for details). This means that the entity marked as read only is never considered for updates, which means when you call flush on the EntityManager these entities are skipped even if properties changed. Read-Only allows to persist new entities of a kind and remove existing ones, they are just not considered for updates.

Сущность должна быть настроена следующим образом: (документация)

/** @Entity(readOnly=true) */

Кэш второго уровня и только чтение для вашей ProductCategory:

Итак, после настройки второго уровня кэширования только для чтения, например, с регионом с именем read_only_entity_region, ваша конфигурация для вашего ProductCategory будет выглядеть примерно так:

/**
 * @Entity(readOnly=true)
 * @Cache(usage = "READ_ONLY", region = "read_only_entity_region")
 */
class ProductCategory 
{
    //...your entity definition...
}

Другие вопросы по теме