我有一个数据库,在那里我存储了一些固定值,如产品类别。当我创建一个新产品并想为其分配一个类别时,我这样做:
$categories = new ProductCategoryRepository();
$category = $categories->find(ProductCategory::EXAMPLE);
$product = new Product();
$product->setCategory($category);
但是,我不确定为什么我必须一直查找数据库才能获取我的应用程序已经知道的静态实体。
静态分配类别就足够了。也许是这样的:
$category = ProductCategory::EXAMPLE;
现在,Doctrine 应该保留具有正确 ID 的关系(由 ProductCategory 类描述(这可能是一个实体?)),我不再需要在数据库中查找静态属性。
我还不知道该怎么做。我可以一直创建新实体,但这似乎不正确,因为这些值已经存储在数据库中,并且它们始终相同而不是新实体。
$category = new ProductCategory::EXAMPLE;
但是,从产品中获取关系应将属性作为实体返回:
$category = $product->getCategory();
return $category instanceof ProductCategory; // true
有没有办法实现这种行为?
这与其说是性能调整,不如说是一个架构问题。我不想多次描述信息(db 条目、php 常量、实体关系等)。
Doctrine 中有一种叫做"二级缓存"的东西,但该功能被认为是实验性的,在使用它之前,您可能应该仔细阅读文档。 引用此功能的官方文档:
二级缓存
第二级缓存功能目前标记为实验性。这是一个非常复杂的功能,我们不能保证它在所有情况下都能稳定运行。
实体缓存定义是这样完成的:(文档)
/**
* @Entity
* @Cache(usage="READ_ONLY", region="my_entity_region")
*/
为了提高您在问题中提到的此类实体的性能,您还应考虑将它们标记为"只读",这将导致原则 2.1 的性能提高,如在有关提高性能的 Doctrine 文档中可以找到:
只读实体
从原则 2.1 开始,您可以将实体标记为只读(有关详细信息,请参阅元数据映射参考)。这意味着永远不会考虑将标记为只读的实体进行更新,这意味着当您在 EntityManager 上调用 flush 时,即使属性发生更改,也会跳过这些实体。只读允许保留某种新实体并删除现有实体,只是不考虑更新它们。
实体应按如下方式配置:(文档)
/** @Entity(readOnly=true) */
产品类别的二级缓存和只读:
因此,在设置第二级只读缓存后,例如名为read_only_entity_region
ProductCategory
配置的区域将如下所示:
/**
* @Entity(readOnly=true)
* @Cache(usage="READ_ONLY", region="read_only_entity_region")
*/
class ProductCategory
{
//...your entity definition...
}
如果您不希望它每次都命中数据库,则可以将其存储在缓存中:
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
. 您的静态值只是整数 ID,您的产品将具有category_id
但类别本身将被缓存。