如何在Doctrine 2中设置默认值?
如何在Doctrine 2中设置默认值?
Answers:
数据库默认值不“便携式”支持。使用数据库默认值的唯一方法是通过columnDefinition
mapping属性,在该属性中为字段所映射的列指定SQL
代码段(DEFAULT
包括原因在内)。
您可以使用:
<?php
/**
* @Entity
*/
class myEntity {
/**
* @var string
*
* @Column(name="myColumn", type="string", length="50")
*/
private $myColumn = 'myDefaultValue';
...
}
首选PHP级别的默认值,因为这些值也可以在新创建和持久保存的对象上正确使用(持久保存新对象以获取默认值后,Doctrine不会返回数据库)。
<?php
/**
* @Entity
*/
class myEntity {
/**
* @var string
*
* @ORM\Column(name="myColumn", type="integer", options={"default" : 0})
*/
private $myColumn;
...
}
请注意,这使用SQL DEFAULT
,某些字段(例如BLOB
和)不支持SQL TEXT
。
options={"default": 0}
小心使用“,而不是”,因为这会导致我的版本学说的错误。
在您的实体中设置构造函数,并在其中设置默认值。
采用:
options={"default":"foo bar"}
并不是:
options={"default"="foo bar"}
例如:
/**
* @ORM\Column(name="foo", type="smallint", options={"default":0})
*/
private $foo
阅读 Symfony 文档的另一个原因永远不会过时。对于我的具体情况,有一个简单的解决方案,就是将field type
选项empty_data
设置为默认值。
同样,此解决方案仅适用于表单中的空输入将DB字段设置为null的情况。
先前的答案都没有帮助我解决我的特定情况,但我找到了解决方案。
我有一个表单字段,需要执行以下操作:
然后,我尝试了此处给出的所有建议。让我列出它们:
<?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
类上的默认值并将其设置为输入字段值。如果输入字段值为空白,则它将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
这种方式覆盖设置器:
...
/**
* 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('Y-m-d H:m:s');
}
if (!$this->getDtPosted()) { $this->setDtPosted(new \DateTime()); }
这是我为自己解决的方法。以下是MySQL默认值的Entity示例。但是,这还需要在您的实体中设置构造函数,并在其中设置默认值。
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'
columnDefinition
直接使用ORM的目的是从数据库中抽象出来的。该解决方案将破坏可移植性,使您的软件依赖于数据库供应商,还将破坏Doctrine Migrations工具。
也可以在mysql数据库上为我工作:
Entity\Entity_name:
type: entity
table: table_name
fields:
field_name:
type: integer
nullable: true
options:
default: 1
这些都不适合我。我在主义网站上找到了一些文档,说要直接设置该值以设置默认值。
private $default = 0;
这插入了我想要的值。
添加到@romanb辉煌的答案。
这会增加迁移的开销,因为您显然无法创建具有非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");
有了这个答案,我建议您考虑一下为什么首先需要数据库中的默认值?通常,它允许创建不具有null约束的对象。
我也遇到同样的问题。我想将数据库的默认值(自动)添加到实体中。猜猜是什么,我做到了:)
<?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";