使用 YAML 的 Doctrine2 和 Symfony2 的默认列值?

Posted

技术标签:

【中文标题】使用 YAML 的 Doctrine2 和 Symfony2 的默认列值?【英文标题】:Default column value with Doctrine2 and Symfony2 using YAML? 【发布时间】:2012-03-02 00:17:13 【问题描述】:

使用 注释 为给定列设置默认值并初始化实体关系的集合非常简单:

use Doctrine\Common\Collections\ArrayCollection;

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

    /**
     * @ORM\OneToMany(targetEntity="Product", mappedBy="category")
     */
    protected $products;

    /**
     * @ORM\Column(type="bool")
     */
    protected $is_visible;

    public function __construct()
    
        $this->products   = new ArrayCollection();
        $this->is_visible = true; // Default value for column is_visible
    

如何使用 YAML 定义而不手动编写Category.php 来实现相同的效果? __construct() 是唯一的方法吗?

Acme\StoreBundle\Entity\Category:
    type: entity
    id:
        id:
            type: integer
            generator:  strategy: AUTO 
    fields:
        is_visible:
            type: bool
    oneToMany:
        products:
            targetEntity: Product
            mappedBy: category

【问题讨论】:

【参考方案1】:

您可以使用注释或 yaml 中的选项属性为列添加默认值。你可以在doctrine annotation documentation阅读更多内容。

注释示例:

/**
 * @ORM\Column(type="bool", name="is_visible", options="default": false)
 */
protected $isVisible;

YAML 示例:

isVisible:
    type: boolean
    column: is_visible
    options: 
        default: false

【讨论】:

谢谢,如果您在添加必须为所有现有对象设置默认值的新列时担心数据库迁移,这似乎是唯一有效的答案。在 PHP 中设置值仅适用于新对象。【参考方案2】:

我认为您以某种方式误解了注释,因为默认值是通过普通 php 设置的。

/**
 * @ORM\Column(type="bool") <- This is an annotation
 */
protected $is_visible;

public function __construct()

    $this->products   = new ArrayCollection(); // <- This is not an annotation
    $this->is_visible = true; // <- This is not an annotation

使用 YAML 映射作为默认值没有区别。原因很简单,这里你的类是如何看待注释的:

use Doctrine\Common\Collections\ArrayCollection;

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

    /**
     * @ORM\OneToMany(targetEntity="Product", mappedBy="category")
     */
    protected $products;

    /**
     * @ORM\Column(type="bool")
     */
    protected $is_visible;

    public function __construct()
    
        $this->products   = new ArrayCollection();
        $this->is_visible = true; // Default value for column is_visible
    

这就是 YAML 映射的样子:

    use Doctrine\Common\Collections\ArrayCollection;

class Category
   
    protected $id;
    protected $products;
    protected $is_visible;

    public function __construct()
    
        $this->products   = new ArrayCollection();
        $this->is_visible = true; // Default value for column is_visible
    

第二个示例的不同之处在于没有更多注释,因为映射是通过 YAML 完成的。类的构造完全相同。因此,默认值是在构建时设置的,这是在普通 PHP 中完成的。

此任务的注释和 YAML 映射之间没有区别。因此,最重要的是,您需要编辑生成的 PHP 类以放置您的默认值。您无法在 YAML 中设置它并让教义为您放置此代码,至少在我们说话的时候。

也许我误解了你的问题:),如果是这样,请不要犹豫,纠正我。

希望对你有帮助。

问候, 马特

【讨论】:

没有注释对我来说很清楚(也许我的英语不太好解释)。但是您确认了我的意思:使用 YAML 您必须编辑生成的 PHP 类才能设置默认值,对吧?没有其他方法可以做到这一点吗? 注解也无法做到这一点。您必须手动添加构造方法并添加默认值。 是的,正如您所说并@Boo 确认,您需要将默认值直接放入生成的PHP 类中。我已经编辑了我的答案以突出这一事实。 而不是使用构造函数,你应该做一些类似 protected $is_visible = true; 的事情。如果它真的很重要,那不是肯定的,但我知道学说在不调用构造函数的情况下水合它的对象。反正代码少了。 @Cerad 真的是真的吗but I do know that doctrine hydrates it's objects without calling the constructor?我一直想知道 Doctrine 用于补水实体的算法到底是什么。我现在正在处理的问题:如何在现有填充数据库上更新架构(即添加字段)时确保数据的完整性。因为这个字段以前不存在,它的默认值应该是什么。 . 以及如何应对它。【参考方案3】:

您可以尝试使用columnDefinition 添加默认值,但它是DDL,它取决于特定的 DBMS(坏事)。按照您的示例,使用 mysql 的字段 *is_visible*:

is_visible:
    type: bool
    columnDefinition: is_visible tinyint(1) NOT NULL DEFAULT '1'

一般来说,这不是一个好主意,我们鼓励您使用构造函数方法或通过实体类中的代码进行属性初始化...

【讨论】:

【参考方案4】:

时间已经过去了。现在可以通过 yaml 设置列的默认值了。

columnName:
     type: string
     options:
          default: "someText"

【讨论】:

以上是关于使用 YAML 的 Doctrine2 和 Symfony2 的默认列值?的主要内容,如果未能解决你的问题,请参考以下文章

使用 YAML 进行地理空间索引“未找到字段映射”

原则 2:有没有办法使用 yaml 或 xml 从 trait 继承映射?

犰狳 eigs_sym:分解失败

Doctrine2:使用 NativeQuery 和 ResultSetMapping 进行查询

Zend+Doctrine2:如何使用 ArrayCollections() 正确刷新实体?

Doctrine2 - 一次多次插入