Doctrine2 Query where Subquery would be needed



让我先介绍一下这个例子中使用的实体:

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。因此,对于一个Order,可以有多个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对象并手动找出哪个是最新的,或者我是否可以以某种方式预先选择?

我找到了一种不完全是我想要的方法,但它不需要对我的应用程序进行任何更改,所以只要我没有找到更好的解决方案就可以了。

我要做的是将实际状态直接存储在Order中。通过LifecycleCallbacks,我将在创建与之相关的OrderStatus后立即更新订单。

Order-Object是这样的

/**
 * @ORMEntity
 * @ORMTable(name="_order")
 */
class Order{
  /**
   * @ORMId
   * @ORMColumn(type="integer")
   * @ORMGeneratedValue(strategy="AUTO")
   */
  protected $id;
  //..
  /**
   * @ORMColumn(type="smallint", nullable=false)
   */
  protected $status = -1;
  // Getter and Setter!
}

我的Order-Status看起来像这样:

/**
 * @ORMEntity
 * @ORMTable(name="order_status")
 * @ORMHasLifecycleCallbacks
 */
class OrderStatus{
  /**
   * @ORMId
   * @ORMColumn(type="integer")
   * @ORMGeneratedValue(strategy="AUTO")
   */
  protected $id;
  /**
   * @ORMManyToOne(targetEntity="Order", inversedBy="order_status", cascade={"persist"})
   * @ORMJoinColumn(name="order_id", referencedColumnName="id", nullable=false)
   */
  protected $order;
  /**
   * @ORMColumn(type="smallint", nullable=false)
   */
  protected $statuscode;
  // ..
  /**
   * @ORMprePersist
   */
  public function prePersist(){
    $this->order->setStatus($this->statuscode);
  }
  // Getter and Setter!
}

注意OrderStatus中的, cascade={"persist"},这样当OrderStatus被持久化时,Order也将被持久化,否则状态将被设置,但不被存储!

这个解决方案的好处是,我现在通过调用$order->getStatus()而不是查询数据库的状态来获得OrderStatus,并且我能够执行$repository->findByStatus(0)。另一方面,如果状态字段由于某些错误而改变,则数据将不一致。

如前所述,如果你有一个解决方案,我不需要一个额外的字段来存储状态,发布它!我对更好的解决方案很感兴趣!

相关内容

最新更新