Doctrine中的默认值

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

数据库默认值不是“可移植的”支持的。 使用数据库默认值的唯一方法是通过columnDefinition映射属性,在该属性中为字段映射到的列指定SQL片段(包含DEFAULT cause)。

您可以使用:

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

PHP级别的默认值是首选,因为这些值在新创build和保留的对象上也可以正常使用(在保留新对象以获取默认值后,Doctrine不会返回到数据库)。

 @ORM\Column(name="foo", type="decimal", precision=7, scale=2, options={"default" : 0}) 

请注意,这使用SQL DEFAULT ,对于某些字段(如BLOBTEXT )不支持。

在你的实体中设置一个构造函数,并在那里设置默认值。

使用:

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

并不是:

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

例如:

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

更新

阅读 Symfony 文档的另一个原因永远不会走出趋势。 对于我的具体情况,有一个简单的解决scheme,并将field type选项empty_data设置为默认值。

同样,这种解决scheme仅适用于表单中的空input将DB字段设置为空的情况。

背景

以前的答案没有帮助我与我的具体情况,但我find了一个解决scheme。

我有一个表单域需要performance如下:

  1. 不需要,可以留空。 (使用'required'=> false)
  2. 如果留空,则应该默认为给定的值。 为了更好的用户体验,我没有在input字段上设置默认值,而是使用了html属性“placeholder”,因为它不那么突兀。

然后我尝试了这里给出的所有build议。 让我列出他们:

  • 为实体属性设置默认值:
 <?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使用你的实体类。

重要

Symfony表单字段覆盖在Entity类上设置的默认值。 意思是说,你的数据库的模式可以定义一个默认值,但是如果你在提交表单的时候把一个非必填字段留空,你的form->isValid()方法中的form->handleRequest()会覆盖这些默认值您的Entity类,并将其设置为input字段值。 如果input字段值为空白,则将Entity属性设置为null

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

我的解决方法

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

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

不是一个美丽的解决scheme,但工作 我可以做一个validation group但是可能有人把这个问题看作是数据转换,而不是数据validation ,我把它留给你来决定。


覆盖安装程序(不起作用)

我也尝试以这种方式覆盖Entity设置器:

 ... /** * 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()以获得更多细节)。

我使用的解决方法是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('Ymd H:m:s'); } 

你也可以用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> 

为我在MySQL数据库上工作也:

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

这是我为自己解决的。 以下是一个具有MySQL默认值的实体示例。 然而,这也需要在你的实体中build立一个构造函数,并且在那里设置默认值。

 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' 

这一切都为我工作。 我在教条的网站上发现了一些说直接设置值来设置默认值的文档。

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

 private $default = 0; 

这插入了我想要的值。

添加到@romanb辉煌的答案。

这在迁移中增加了一些开销,因为你显然不能创build一个非null约束的字段而且没有默认值。

 // 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"); 

有了这个答案,我鼓励你想一想,为什么你需要首先在数据库中的默认值? 通常是允许创build具有非空约束的对象。

如果你为你的实体使用yaml定义,下面的代码在我的postgresql数据库上工作:

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

我也遇到了同样的问题。 我想从数据库的默认值(自动)到实体。 猜猜看,我做到了:)

 <?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"; 

虽然在构造函数中设置值是可行的,但使用Doctrine生命周期事件可能是更好的解决scheme。

通过利用prePersist生命周期事件,您可以仅在初始持久化时在实体上设置默认值。

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