大家好,这是我的第一个问题!
我想要一个实体,带有一个指示顺序的字段,例如具有顺序 1 的实体实例 1,具有顺序 2 的实体实例 2,具有顺序 3 的实体实例 3 等。然后,例如,我想创建一个新实例,并给它订单 2。因此,结果将是顺序为 1 的 EntityInstance1、顺序为 2 的 EntityInstance4、顺序为 3 的 EntityInstance2 和顺序为 4 的实体实例 3。假设我删除了 EntityInstance1,所以我将有顺序为 1 的 EntityInstance4,顺序为 2 的 EntityInstance2,顺序为 3 的 EntityInstance3。这怎么可能实现??
谢谢!!!
嗯...我真的不知道为什么有人会做这样的事情,但好吧,这是可以实现的。让我们合乎逻辑地思考。1)您有多个同一对象的实例=>表示您有一个对象的集合2)集合具有某种迭代器3) 您可以使用迭代器遍历列表并更新实例顺序。
因此,实现愿景的最简单但最昂贵的方法是:
$objectCollection = $this -> get('doctrine.orm.entity_manager') -> getRepository('YOUR_ENTITY') -> findBy(array(),array('order','asc'));
$iterator = $objectCollection -> getArrayIterator();
$i = 1;
while($object = $iterator -> next()){
$object -> setOrder($i);
$i++;
}
$this -> get('doctrine.orm.entity_manager') -> flush();
注意:订单不能用作属性名称。因此,您需要另一个名称,并在代码示例中更改它。
让它工作了!使用生命周期事件和批量更新!
这是我的实体:
namespace LuchoNatIcnaWebsiteBackendBundleEntity;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;
/**
* Meeting
*
* @ORMTable()
* @ORMEntity(repositoryClass="LuchoNatIcnaWebsiteBackendBundleEntityMeetingRepository")
*/
class Meeting {
/* ***************************************************************************************/
/* Properties ****************************************************************************/
/* ***************************************************************************************/
// Mapped
/**
*
* @var integer @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* @var string @ORMColumn(name="name", type="string", length=255, nullable=false)
* @AssertNotBlank(message="El campo nombre es obligatorio")
*/
private $name;
/**
*
* @var integer @ORMColumn(name="production_order", type="integer", nullable=true)
*/
private $productionOrder;
/**
*
* @var integer @ORMColumn(name="staging_order", type="integer", nullable=true)
*/
private $stagingOrder;
/**
*
* @var boolean @ORMColumn(name="production_enabled", type="boolean", nullable=false)
*/
private $productionEnabled;
/**
*
* @var boolean @ORMColumn(name="staging_enabled", type="boolean", nullable=false)
*/
private $stagingEnabled;
/* ***************************************************************************************/
/* Getters & Setters *********************************************************************/
/* ***************************************************************************************/
/**
* Get id
*
* @return integer
*/
public function getId() {
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Meeting
*/
public function setName($name) {
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName() {
return $this->name;
}
/**
* Set productionOrder
*
* @param integer $productionOrder
* @return Meeting
*/
public function setProductionOrder($productionOrder) {
$this->productionOrder = $productionOrder;
return $this;
}
/**
* Get productionOrder
*
* @return integer
*/
public function getProductionOrder() {
return $this->productionOrder;
}
/**
* Set stagingOrder
*
* @param integer $stagingOrder
* @return Meeting
*/
public function setStagingOrder($stagingOrder) {
$this->stagingOrder = $stagingOrder;
return $this;
}
/**
* Get stagingOrder
*
* @return integer
*/
public function getStagingOrder() {
return $this->stagingOrder;
}
/**
* Set productionEnabled
*
* @param boolean $productionEnabled
* @return Meeting
*/
public function setProductionEnabled($productionEnabled) {
$this->productionEnabled = $productionEnabled;
return $this;
}
/**
* Get productionEnabled
*
* @return boolean
*/
public function getProductionEnabled() {
return $this->productionEnabled;
}
/**
* Set stagingEnabled
*
* @param boolean $stagingEnabled
* @return Meeting
*/
public function setStagingEnabled($stagingEnabled) {
$this->stagingEnabled = $stagingEnabled;
return $this;
}
/**
* Get stagingEnabled
*
* @return boolean
*/
public function getStagingEnabled() {
return $this->stagingEnabled;
}
/* ***************************************************************************************/
/* Other Methods *************************************************************************/
/* ***************************************************************************************/
}
然后,这里是事件侦听器
namespace LuchoNatIcnaWebsiteBackendBundleEventListener;
use DoctrineCommonEventSubscriber;
use DoctrineORMEventLifecycleEventArgs;
use LuchoNatIcnaWebsiteBackendBundleEntityMeeting;
class MeetingIndexerSubscriber implements EventSubscriber
{
public function getSubscribedEvents() {
return array(
'prePersist',
'preUpdate',
'postRemove'
);
}
public function prePersist(LifecycleEventArgs $args) {
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();
if($entity instanceof Meeting) {
$stagingOrder = $entity->getStagingOrder();
if(isset($stagingOrder)) {
$dql = "UPDATE LuchoNatIcnaWebsiteBackendBundleEntityMeeting
m set m.stagingOrder = m.stagingOrder + 1
WHERE m.stagingOrder >= $stagingOrder";
$entityManager->createQuery($dql)->execute();
}
$productionOrder = $entity->getProductionOrder();
if(isset($productionOrder)) {
$dql = "UPDATE LuchoNatIcnaWebsiteBackendBundleEntityMeeting
m set m.productionOrder = m.productionOrder + 1
WHERE m.productionOrder >= $productionOrder";
$entityManager->createQuery($dql)->execute();
}
}
}
public function preUpdate(LifecycleEventArgs $args) {
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();
if($entity instanceof Meeting) {
if($args->hasChangedField('stagingOrder')) {
if($args->getNewValue('stagingOrder') > $args->getOldValue('stagingOrder')) {
$dql = 'UPDATE LuchoNatIcnaWebsiteBackendBundleEntityMeeting
m set m.stagingOrder = m.stagingOrder - 1
WHERE m.stagingOrder > ' . $args->getOldValue('stagingOrder') .
' AND m.stagingOrder <= ' . $args->getNewValue('stagingOrder');
$entityManager->createQuery($dql)->execute();
}
if($args->getNewValue('stagingOrder') < $args->getOldValue('stagingOrder')) {
$dql = 'UPDATE LuchoNatIcnaWebsiteBackendBundleEntityMeeting
m set m.stagingOrder = m.stagingOrder + 1
WHERE m.stagingOrder >= ' . $args->getNewValue('stagingOrder') .
' AND m.stagingOrder < ' . $args->getOldValue('stagingOrder');
$entityManager->createQuery($dql)->execute();
}
}
if($args->hasChangedField('productionOrder')) {
if($args->getNewValue('productionOrder') > $args->getOldValue('productionOrder')) {
$dql = 'UPDATE LuchoNatIcnaWebsiteBackendBundleEntityMeeting
m set m.productionOrder = m.productionOrder - 1
WHERE m.productionOrder > ' . $args->getOldValue('productionOrder') .
' AND m.productionOrder <= ' . $args->getNewValue('productionOrder');
$entityManager->createQuery($dql)->execute();
}
if($args->getNewValue('productionOrder') < $args->getOldValue('productionOrder')) {
$dql = 'UPDATE LuchoNatIcnaWebsiteBackendBundleEntityMeeting
m set m.productionOrder = m.productionOrder + 1
WHERE m.productionOrder >= ' . $args->getNewValue('productionOrder') .
' AND m.productionOrder < ' . $args->getOldValue('productionOrder');
$entityManager->createQuery($dql)->execute();
}
}
}
}
public function postRemove(LifecycleEventArgs $args) {
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();
if($entity instanceof Meeting) {
$stagingOrder = $entity->getStagingOrder();
if(isset($stagingOrder)) {
$dql = "UPDATE LuchoNatIcnaWebsiteBackendBundleEntityMeeting
m set m.stagingOrder = m.stagingOrder - 1
WHERE m.stagingOrder > $stagingOrder";
$entityManager->createQuery($dql)->execute();
}
$productionOrder = $entity->getProductionOrder();
if(isset($productionOrder)) {
$dql = "UPDATE LuchoNatIcnaWebsiteBackendBundleEntityMeeting
m set m.productionOrder = m.productionOrder - 1
WHERE m.productionOrder > $productionOrder";
$entityManager->createQuery($dql)->execute();
}
}
}
}
最后,在配置文件中:
services:
meeting.indexer_suscriber:
class: LuchoNatIcnaWebsiteBackendBundleEventListenerMeetingIndexerSubscriber
tags:
- { name: doctrine.event_subscriber, connection: default }
它有效!!
我使用了Symfony 2:如何注册事件侦听器和订阅者和Doctrine 2:事件文档!