새로운 또는 업데이트 된 모델 엔터티를 어떻게 저장해야합니까?


10

Magento 2에는 리포지토리 클래스가 있습니다. save()Magento 1.9에서 많이 사용되는 고전적인 방법 은 2.04 또는 2.05에서 더 이상 사용되지 않습니다. 나는 팩토리를 사용하여 새 객체를 만들고 new의 속성을 설정 한 후 예를 들어 제품이라고 부릅니다 save().

$productFactory->create()->setName()...->save()

반면에 우리는 method도 포함하는 저장소를 가지고 있습니다 save. 나는 이것을 간단히 말해서 사용하고 있습니다 :

$product = $productFactory->create()->setName()... $productRepository->save($product)

내 코드에는 두 가지 방식으로 작동하는 클래스가 있습니다. 또한 때로는 다른 방법으로 다른 행동을 의미하는 것으로 나타났습니다. 리포지토리를 사용하여 데이터를 추가로 확인하는 방법이 있습니까?

어떤 방법으로해야합니까?

답변:


10

먼저 다음 과 같은 모델에서이 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 ....

이 메소드는 $ product 유형의 오브젝트가 \Magento\Catalog\Api\Data\ProductInterface전달 될 것으로 예상 하지만 기본적으로 이로 해결됩니다 Magento\Catalog\Model\Product.

500 번 줄 아래에서 아래를 내려다 보면서 try, 우리 는 성명을보고

$this->resourceModel->save($product);

당신은 잘 추측했다! 77 번째 줄 에서 속성으로 선언 된 $this->resourceModel유형 입니다.\Magento\Catalog\Model\ResourceModel\Productprotected

다시 말하지만 ResourceModel실제로는 절약이됩니다.

그러나 444 ~ 500 행은 실제로 귀하의 질문에 대한 답변입니다. 실제로 여기에서 실행되는 모든 코드는 직접 모델 저장과이 저장소 저장 방법 사이의 동작에 차이가 생길 수 있습니다.

예를 들어 ignore_links_flag로 설정되어 있으면 제품 리포지토리에서 제품 링크를 가져오고 처리합니다. 제품 0이 기존 제품인지 확인하십시오.

향후 제품 저장 방법을 변경해야 할 경우 제품 모델 대신 제품 리포지토리를 재정의하는 것이 더 나은 방법이라고 결론을 내릴 수 있습니다.

제품 저장 및 업데이트도 마찬가지입니다. 제품 저장소 개체를 사용하고 싶습니다.

나는 또한 /vendor/magento/module-cms/Model/PageRepository.php를 친절하게 참조합니다.

리포지토리를 통해 CMS 페이지를 저장하는 방법입니다. 여기서는 더 간단합니다. 상점 ID가 설정되고 자원 모델이 즉시 저장되도록 호출됩니다.

이 마지막 공지로, 어떤 경우에는 저장소와 모델 저장간에 큰 차이가 없을 수도 있지만, 어쨌든 필요할 때마다이를 발견 할 수 있기를 바랍니다.


1

\Magento\Catalog\Api\Data\ProductInterface모델 대신 데이터 인터페이스 (예 :)를 사용하고 리포지토리를 사용하여 모델을로드하고 저장하는 것이 좋습니다.

마 젠토 개발자 문서 참조


1
좋아-그것은 전체 엔티티에 대한 올바른 방법이지만-일부 속성 값을 업데이트하기 만합니다. 전체 엔티티를로드 / 저장하는 것은 권장되지 않습니다.
Bartosz Kubicki
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.