2011-11-17 50 views
0

讓我先介紹一下本例中使用的實體:Doctrine2查詢哪裏會需要子查詢

Order (_order in mysql) 
    $id (primary key, auto increment) 
OrderStatus (order_status in mysql) 
    $id (primary key, auto increment) 
    $order (storing the order object it is related to, named order_id in mysql) 
    $statuscode (Storing the integer code) 
    $created_at (Storing the datetime of creation) 

的關係是Order n:1 OrderStatus。對於每個狀態更改,我使用新的狀態碼創建一個新的OrderStatus。所以對於一個訂單,可以有許多OrderStatus。實際的OrderStatus可以通過查看具有最新的created_at的OrderStatus來計算出來。

我現在想要獲取所有狀態爲0的對象。在SQL中,我的查詢如下所示:

SELECT o.id,os.statuscode,os.created_at 
FROM `_order` o 
LEFT JOIN `order_status` os ON o.id = os.order_id 
WHERE os.created_at = (SELECT MAX(created_at) 
         FROM order_status 
         WHERE order_id = os.order_id); 

我可以在DQL中做這樣的查詢嗎?還是必須使用對象?如果是這樣,我是否需要閱讀所有OrderStatus對象並手動確定哪一個是最新的對象,或者我可以以某種方式預選?

回答

0

我想出了一種並不完全符合我的要求的方式,但它不需要對應用程序進行任何更改,所以只要沒有找到更好的解決方案就沒關係。

我要做的是我將直接在訂單中存儲實際狀態。通過LifecycleCallbacks,一旦與其相關的OrderStatus被創建,我將立即更新訂單。

所以我的訂單對象看起來是這樣的:

/** 
* @ORM\Entity 
* @ORM\Table(name="_order") 
*/ 
class Order{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    //.. 

    /** 
    * @ORM\Column(type="smallint", nullable=false) 
    */ 
    protected $status = -1; 

    // Getter and Setter! 
} 

我OrderStatus看起來就像這樣:

/** 
* @ORM\Entity 
* @ORM\Table(name="order_status") 
* @ORM\HasLifecycleCallbacks 
*/ 
class OrderStatus{ 

    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="Order", inversedBy="order_status", cascade={"persist"}) 
    * @ORM\JoinColumn(name="order_id", referencedColumnName="id", nullable=false) 
    */ 
    protected $order; 

    /** 
    * @ORM\Column(type="smallint", nullable=false) 
    */ 
    protected $statuscode; 

    // .. 

    /** 
    * @ORM\prePersist 
    */ 
    public function prePersist(){ 
    $this->order->setStatus($this->statuscode); 
    } 

    // Getter and Setter! 
} 

心靈的, cascade={"persist"}的OrderStatus內使訂單也將持續時OrderStatus被持久化,否則狀態將被設置,但不被存儲!

這個解決方案的好處是,我現在通過調用$order->getStatus()來獲得OrderStatus,而不必查詢數據庫的狀態,並且我能夠做到$repository->findByStatus(0)。另一方面,由於某種錯誤導致狀態字段發生變化的時刻,數據將不一致。

如上所述,如果您有一個解決方案,我不需要額外的字段來存儲狀態,請發佈!我對更好的解決方案非常感興趣!