首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Symfony2中处理SQL触发器?

如何在Symfony2中处理SQL触发器?
EN

Stack Overflow用户
提问于 2013-08-22 10:17:14
回答 2查看 11.8K关注 0票数 8

在我的Symfony2 2/Doctrine2webapp中有一个User实体。这个用户有一个属性last_updated来标识最近的时间,任何事情都变了。我在数据库中将这个属性设置为NOT NULL。到现在为止还好。

我认为在数据库中创建一个SQL触发器是一个很好的实践,它将这个last_updated设置为在每个INSERTUPDATE上的NOW()。所以你不必在你的申请中关心这个问题。这就是我所做的,我在我的数据库中实现了这个触发器。

但是如果我现在在我的应用程序中创建一个用户

代码语言:javascript
复制
$user = new User();
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();

我收到Symfony的一条错误消息:

使用params 'INSERT INTO User (username, ..., last_updated) VALUES (?, ..., ?)'执行["johndoe", ..., null]:时发生异常 SQLSTATE23000:完整性约束违反: 1048列'last_updated'不能为空

问题很明显: Symfony试图使用参数INSERT-statement为last_updated向数据库发送null,这是不允许的--因为这个属性可能不是null。

我很快就能想到两个解决办法:

  • 解决方法之一是将last_updated字段从实体描述中删除。然后Symfony将不会尝试将任何内容传递给该列的数据库,并且触发器将设置适当的值。但我不认为这是一个好方法,因为只要我尝试更新db模式(doctrine:schema:update --force),我就会释放last_updated-column。
  • 另一个解决办法是:在我的$user->setLastUpdated(new \DateTime())flush()之前执行persist()。但这将尽量减少在我的数据库中使用触发器的好处,以避免在我的应用程序中关心它。

有没有办法让Symfony/Doctrine知道我的数据库上有一个触发器在运行?如果不是,(如何)我可以连接到Symfony/Doctrine来实现一个适当的解决方案?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-22 20:20:42

若要引用google组对此问题的答复:

数据库端代码(如触发器和函数)倾向于破坏使用ORM (如Propel或Doctrine )开发软件的好处,因为使用ORM的最大优势之一是数据库不可知论。通过拥有数据库端触发器和函数,您将自己绑定到数据库上,因此使用ORM几乎没有什么好处。-GarethMc

ML9Dy0Rw

为此,最好像Faery建议的那样使用生命周期回调。一个简单的函数将处理更新该字段,这样如果您决定在将来更改数据库,就不必担心它。

代码语言:javascript
复制
//In Your Entity File EX: SomeClass.php
/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks()
 */
class SomeClass
{
    ....

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function prePersistPreUpdate()
    {
        $this->last_modified = new \DateTime();
    }
}

还请参阅生命周期回调的引用。

在您的示例中,您将向用户实体类添加生命周期回调函数和注释。SomeClass只是一个示例类,它表明生命周期回调不仅仅对用户实体有好处。

票数 15
EN

Stack Overflow用户

发布于 2015-06-09 13:56:33

另一个(更容易和更广泛的)选项是使用Gedmo的Timestampable原则扩展。这样,您可以简单地注释实体字段,以便在create或update上加盖时间戳。

示例:

代码语言:javascript
复制
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

class MyEntity
{
    ...

    /**
     * @var \DateTime $lastUpdated
     *
     * @Gedmo\Timestampable(on="update")
     * @ORM\Column(name="last_updated", type="datetime")
     */
    private $lastUpdated;

    ...
}

https://packagist.org/packages/gedmo/doctrine-extensions

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18377690

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档