Doctrine中的默认值

时间:2010-07-31 04:59:15

标签: php orm doctrine-orm

如何在Doctrine 2中设置默认值?

15 个答案:

答案 0 :(得分:482)

<?php
/**
 * @Entity
 */
class myEntity {
    /**
     * @var string
     *
     * @ORM\Column(name="myColumn", type="integer", options={"default" : 0})
     */
    private $myColumn;
    ...
}

请注意,这会使用SQL DEFAULTBLOBTEXT等字段不支持SQL。{/ p>

答案 1 :(得分:360)

数据库默认值不受“支持”支持。使用数据库默认值的唯一方法是通过columnDefinition映射属性,为该字段映射到的列指定SQL代码段(DEFAULT原因包含)。

您可以使用:

<?php
/**
 * @Entity
 */
class myEntity {
    /**
     * @var string
     *
     * @Column(name="myColumn", type="string", length="50")
     */
    private $myColumn = 'myDefaultValue';
    ...
}

首选PH​​P级别的默认值,因为它们也适用于新创建的和持久化的对象(在持久保存新对象以获取默认值后,Doctrine不会返回数据库)。

答案 2 :(得分:61)

在您的实体中设置构造函数并在那里设置默认值。

答案 3 :(得分:54)

使用:

options={"default":"foo bar"}

而不是:

options={"default"="foo bar"}

例如:

/**
* @ORM\Column(name="foo", type="smallint", options={"default":0})
*/
private $foo

答案 4 :(得分:49)

更新

为Symfony 阅读文档的另一个原因永远不会超出趋势。我的具体案例有一个简单的解决方案,就是将field type选项empty_data设置为默认值。

同样,此解决方案仅适用于表单中的空输入将DB字段设置为null的情况。

背景

以前的答案都没有帮助我解决我的具体情况,但我找到了解决方案。

我有一个表单字段需要表现如下:

  1. 不需要,可以留空。 (使用'required'=&gt; false)
  2. 如果留空,则应默认为给定值。为了更好的用户体验,我没有在输入字段上设置默认值,而是使用了html属性'placeholder',因为它不那么突兀。
  3. 然后我尝试了这里给出的所有建议。让我列出一下:

    • 为实体属性设置默认值:
    <?php
    /**
     * @Entity
     */
    class myEntity {
        /**
         * @var string
         *
         * @Column(name="myColumn", type="string", length="50")
         */
        private $myColumn = 'myDefaultValue';
        ...
    }
    
    • 使用选项注释:
    @ORM\Column(name="foo", options={"default":"foo bar"})
    
    • 在构造函数上设置默认值:
    /**
     * @Entity
     */
    class myEntity {
        ...
        public function __construct()
        {
            $this->myColumn = 'myDefaultValue';
        }
        ...
    }
    
    它们都不起作用,因为Symfony如何使用您的Entity类。

    重要

    Symfony表单字段覆盖在Entity类上设置的默认值。 这意味着,您的数据库架构可以定义默认值,但如果您在提交表单时将非必填字段留空,则form->handleRequest()方法中的form->isValid()将覆盖Entity方法中的默认值{1}}类并将它们设置为输入字段值。如果输入字段值为空,则会将Entity属性设置为null

    http://symfony.com/doc/current/book/forms.html#handling-form-submissions

    我的解决方法

    form->handleRequest()方法中form->isValid()之后设置控制器上的默认值:

    ...
    if ($myEntity->getMyColumn() === null) {
        $myEntity->setMyColumn('myDefaultValue');
    }
    ...
    

    不是一个漂亮的解决方案,但它有效。我可以制作一个validation group,但可能会有人将此问题视为数据转换而不是数据验证,我会留待您决定。


    覆盖设置器(不起作用)

    我还试图以这种方式覆盖Entity setter:

    ...
    /**
     * Set myColumn
     *
     * @param string $myColumn
     *
     * @return myEntity
     */
    public function setMyColumn($myColumn)
    {
        $this->myColumn = ($myColumn === null || $myColumn === '') ? 'myDefaultValue' : $myColumn;
    
        return $this;
    }
    ...
    

    即使它看起来更干净,它也不起作用。原因是邪恶的form->handleRequest()方法不使用模型的setter方法来更新数据(深入了解form->setData()以获取更多细节)。

答案 5 :(得分:16)

我使用的解决方法是LifeCycleCallback。仍在等待查看是否还有“本机”方法,例如@Column(type="string", default="hello default value")

/**
 * @Entity @Table(name="posts") @HasLifeCycleCallbacks
 */
class Post implements Node, \Zend_Acl_Resource_Interface {

...

/**
 * @PrePersist
 */
function onPrePersist() {
    // set default date
    $this->dtPosted = date('Y-m-d H:m:s');
}

答案 6 :(得分:12)

您也可以使用xml:

<field name="acmeOne" type="string" column="acmeOne" length="36">
    <options>
        <option name="comment">Your SQL field comment goes here.</option>
        <option name="default">Default Value</option>
    </options>
</field>

答案 7 :(得分:7)

以下是我为自己解决的问题。下面是一个具有MySQL默认值的实体示例。但是,这还需要在实体中设置构造函数,并在那里设置默认值。

Entity\Example:
  type: entity
  table: example
  fields:
    id:
      type: integer
      id: true
      generator:
        strategy: AUTO
    label:
      type: string
      columnDefinition: varchar(255) NOT NULL DEFAULT 'default_value' COMMENT 'This is column comment'

答案 8 :(得分:7)

也适用于mysql数据库:

Entity\Entity_name:
    type: entity
    table: table_name
    fields: 
        field_name:
            type: integer
            nullable: true
            options:
                default: 1

答案 9 :(得分:6)

这些都不适合我。我在doctrine的网站上找到了一些文档,说明直接设置值以设置默认值。

http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/faq.html

private $default = 0;

这会插入我想要的值。

答案 10 :(得分:3)

如果您为实体使用yaml定义, 以下适用于postgresql数据库:

Entity\Entity_name:
    type: entity
    table: table_name
    fields: 
        field_name:
            type: boolean
            nullable: false
            options:
                default: false

答案 11 :(得分:2)

添加@romanb精彩答案。

这在迁移中增加了一点开销,因为你显然无法创建一个非空约束且没有默认值的字段。

// this up() migration is autogenerated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != "postgresql");

//lets add property without not null contraint        
$this->addSql("ALTER TABLE tablename ADD property BOOLEAN");

//get the default value for property       
$object = new Object();
$defaultValue = $menuItem->getProperty() ? "true":"false";

$this->addSql("UPDATE tablename SET property = {$defaultValue}");

//not you can add constraint
$this->addSql("ALTER TABLE tablename ALTER property SET NOT NULL");

有了这个答案,我建议您先考虑为什么首先需要数据库中的默认值?通常是允许创建非空约束的对象。

答案 12 :(得分:1)

我在同样的问题上挣扎。我希望将数据库中的默认值放入实体(自动)。猜猜看,我做了什么:)

<?php
/**
 * Created by JetBrains PhpStorm.
 * User: Steffen
 * Date: 27-6-13
 * Time: 15:36
 * To change this template use File | Settings | File Templates.
 */

require_once 'bootstrap.php';

$em->getConfiguration()->setMetadataDriverImpl(
    new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
        $em->getConnection()->getSchemaManager()
    )
);

$driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($em->getConnection()->getSchemaManager());
$driver->setNamespace('Models\\');

$em->getConfiguration()->setMetadataDriverImpl($driver);

$cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory();
$cmf->setEntityManager($em);
$metadata = $cmf->getAllMetadata();

// Little hack to have default values for your entities...
foreach ($metadata as $k => $t)
{
    foreach ($t->getFieldNames() as $fieldName)
    {
        $correctFieldName = \Doctrine\Common\Util\Inflector::tableize($fieldName);

        $columns = $tan = $em->getConnection()->getSchemaManager()->listTableColumns($t->getTableName());
        foreach ($columns as $column)
        {
            if ($column->getName() == $correctFieldName)
            {
                // We skip DateTime, because this needs to be a DateTime object.
                if ($column->getType() != 'DateTime')
                {
                    $metadata[$k]->fieldMappings[$fieldName]['default'] = $column->getDefault();
                }
                break;
            }
        }
    }
}

// GENERATE PHP ENTITIES!
$entityGenerator = new \Doctrine\ORM\Tools\EntityGenerator();
$entityGenerator->setGenerateAnnotations(true);
$entityGenerator->setGenerateStubMethods(true);
$entityGenerator->setRegenerateEntityIfExists(true);
$entityGenerator->setUpdateEntityIfExists(false);
$entityGenerator->generate($metadata, __DIR__);

echo "Entities created";

答案 13 :(得分:1)

虽然在构造函数中设置值可行,但使用Doctrine Lifecycle事件可能是更好的解决方案。

通过利用prePersist生命周期事件,您可以仅在初始保留时为您的实体设置默认值。

答案 14 :(得分:0)

在属性定义上设置默认值时要小心!在构造函数中执行它,以保持它没有问题。如果在属性定义上定义它,则将对象持久保存到数据库,然后进行部分加载,然后未加载的属性将再次具有默认值。如果你想再次坚持这个对象,这很危险。