簡體   English   中英

如何根據相關實體的值查詢

[英]How to query related entities based on their value

我的網站上有廣告。 要公開展示廣告,必須付費。 廣告是公開的或已付款的,如果沒有未付款項,或者已付款。

我想要的是檢索所有公共廣告,但這需要使用此方法進行大量查詢。 我正在尋找更好的方法。

這里有更多字段,但讓我們關注payments字段。 這是一對多的。

class Ad
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;


    /**
     * @var string
     *
     * @ORM\Column(name="title", type="string", length=255,nullable=true)
     */
    private $adTitle;


    /**
     * @var string
     *
     * @ORM\Column(name="description", type="string", length=255,nullable=true)
     */
    private $description;



    /**
     * @ORM\ManyToOne(targetEntity="Application\FOS\UserBundle\Entity\User")
     * @ORM\JoinColumn(name="advertiser")
     */
    private $advertiser;


    /**
     * @ORM\OnetoMany(targetEntity="MyBundle\Entity\Payment",mappedBy="ad",cascade={"persist"})
     * @ORM\JoinColumn(name="payments", referencedColumnName="id",nullable=true)
     */
    private $payments;

}

對於付款,我使用的是PayumBundle,因此實體看起來像這樣:

use Payum\Core\Model\Payment as BasePayment;
class Payment extends BasePayment
{
    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     *
     * @var integer $id
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="MyBundle\Entity\Ad",inversedBy="payments",cascade={"persist"})
     * @ORM\JoinColumn(name="ad", referencedColumnName="id",nullable=true)
     */
    protected $ad;


}

目前,我正在使用執行以下操作的服務:

  public function getAllPublicAds()
    {
        $allAds = $this->em->getRepository('MyBundle:Ad')->findAll();

        $publicAds=array();

        foreach($allAds as $ad){
            if($this->isPublicAd($ad)) array_push($publicAds,$ad);
        }

        return $publicAds;

    }

我正在獲取所有廣告,如果它們是公開的,則將它們放到一個數組中,稍后將進入樹枝視圖。

如果廣告的所有付款均已支付,則該廣告為公開廣告,因此:

public function isPublicAd(Ad $ad)
{

    $payments = $ad->getPayments();

    if (!count($payments)) {
        return false;
    } else {
        foreach ($payments as $payment) {
            if (!$this->paidPayment($payment)) return false;
        }

        return true;
    }
 }

最后,如果表中的明細字段“已付款”為真,則將支付已付款。 這就是PayumBundle的工作方式。 它會創建一個令牌,然后在您使用該令牌為您的對象付款后,將有關付款的詳細信息填充到該對象的“付款”字段中。 您可以在這里找到課程。 我的付款課程從上面進行了擴展。 因此,我正在檢查這些詳細信息是否已填寫,或者“已付款”字段為true。

public function paidPayment(Payment $payment)
{
    $details = $payment->getDetails();

    if (array_key_exists("paid", $details) && $details["paid"]) return true;

    else return false;

}

問題在於,這將對數據庫創建非常大量且不必要的查詢。 可以縮短這個時間嗎? 我不確定我是否可以在沒有Doctrine的情況下使用普通查詢,因為我需要在收到數據庫結果后檢查details ['paid']字段,而這只能在控制器或服務中進行。 如果在查詢中甚至可以做到這一點,我也不知道,也似乎沒有找到解決方法。

您應該使用QueryBuilder而不是findAll方法。 在這種情況下,您可以指定需要匹配的條件(就像在普通sql )。

所以:

$paidAds =  $this->em->getRepository('MyBundle:Ad')
                ->createQueryBuilder('a')
                ->innerJoin('a.Payments', 'p')
                ->getQuery()
                ->getResult();

實際上,我並沒有對您的數據庫結構進行深入分析,因為innerJoin可能只是您需要的條件,因為您只會獲得與付款有關的Ads

要了解有關QueryBuilder檢查文檔的更多信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM