首先让我们看一下,如果save()
直接在product
模型上使用该方法会发生什么
/**
* @var Magento\Catalog\Model\Product $product
*/
$product->save();
模型类本身是
Magento\Catalog\Model\Product
在此类中,搜索save()方法的定义。
没有找到对吗?好吧,有beforeSave()和afterSave(),但本身没有save()。有趣,不是吗?
然后,我们需要查看的父类Magento\Catalog\Model\Product
。
我们需要通过Magento\Catalog\Model\AbstractModel
和Magento\Framework\Model\AbstractExtensibleModel
,只是最终到达处Magento\Framework\Model\AbstractModel
。
当然,这里有一个save()方法,它看起来像
public function save()
{
$this->_getResource()->save($this);
return $this;
}
现在我们看到,每当在任何模型上调用save()时,都会调用该方法的save()方法AbstractModel
,并且实现是RESOURCE MODEL实际上进行了保存。
考虑到我们总是如此,这最后一个不足为奇,因为就像Magento 1.0中的时间开始一样,几乎为任何实体都创建了模型和资源模型。
现在,让我们看看其ProductRepository
工作原理。
让我们打开文件
/vendor/magento/module-catalog/Api/ProductRepositoryInterface.php
除了其他方法外,此接口还要求有一个save()方法。
谁在实际实现此接口?
让我们打开文件
/etc/di.xml
然后检查第10行
<preference for="Magento\Catalog\Api\ProductRepositoryInterface" type="Magento\Catalog\Model\ProductRepository" />
因此,自然而然地,我们发现了save()方法的重要性
/vendor/magento/module-catalog/Model/ProductRepository
它开始于444行,看起来像
public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveOptions = false)
{
$tierPrices = $product->getData('tier_price');
try {
.... other code here ....
此方法期望\Magento\Catalog\Api\Data\ProductInterface
传递一个类型为$ product的对象,但默认情况下解析为Magento\Catalog\Model\Product
。
在第500行下方向下try
看,在声明中,我们看到类似
$this->resourceModel->save($product);
你猜对了!$this->resourceModel
是type \Magento\Catalog\Model\ResourceModel\Product
,protected
在第77行声明为property。
因此,ResourceModel
实际上,确实可以节省费用。
但是,在444行和500行之间实际上是您问题的答案。实际上,这里执行的所有代码最终可能并且将导致直接模型保存和此存储库保存方式之间的行为差异。
例如,如果将ignore_links_flag
设置为0
,则产品存储库将获取并处理产品链接,首先检查该产品是否为现有产品,等等。
我们可能需要得出结论,如果将来有任何更改产品保存方式的需求,也许更好的方法是重写产品存储库而不是产品模型。
保存和更新产品也是如此。我宁愿使用产品存储库对象。
我也请您参考/vendor/magento/module-cms/Model/PageRepository.php
这就是通过存储库保存CMS页面的方式。在这里,事情变得简单了。设置商店标识,并调用资源模型以立即保存。
有了这最后一条通知,您将得出结论,在某些情况下,存储库和模型保存之间可能不会有太大的区别,但是无论如何,我希望您现在有能力在需要时发现它们。