如何在Doctrine 2中设置一个默认值?
数据库默认值不支持"可移植"。使用数据库默认值的唯一方法是通过 "columnDefinition "映射属性,指定字段所映射的 "SQL "片段(包括 "DEFAULT "原因)。
你可以使用。
<?php
/**
* @Entity
*/
class myEntity {
/**
* @var string
*
* @Column(name="myColumn", type="string", length="50")
*/
private $myColumn = 'myDefaultValue';
...
}
PHP级别的默认值是首选,因为这些默认值在新创建和持久化的对象上也能正常使用(Doctrine不会在持久化一个新对象后回到数据库去获取默认值)。
使用方法:
options={"default":"foo bar"}
options={"default":"foo bar"}
而不是。
options={"default"="foo bar"}
例如:
/**
* @ORM\Column(name="foo", type="smallint", options={"default":0})
*/
private $foo
/**
* @ORM\Column(name="foo", type="smallint", options={"default":0})
*/
private $foo
还有一个原因,为什么阅读Symfony的文档永远不会过时。 针对我的特殊情况,有一个简单的解决方案,就是将 "字段类型 "选项 "empty_data "设置为默认值。
再次强调,这个解决方案只是针对表单中的空输入将DB字段设置为null的情况。
前面的答案都没有帮助我解决我的特殊情况,但我找到了一个解决方案。
我有一个表格字段,需要表现如下。
如果留空,则应默认为给定值。 为了更好的用户体验,我没有在输入字段上设置默认值,而是使用html属性'占位符'。 因为它不太显眼。
然后我尝试了这里给出的所有建议。 让我列出它们。
<?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表单字段覆盖了实体类的默认值。
意思是说,你的DB的模式可以定义一个默认值,但如果你在提交表单时留下一个非必填字段为空,你的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');
}
...
不是一个漂亮的解决方案,但它是有效的。 我也许可以做一个 "验证组",但可能有人把这个问题看成是数据转换,而不是数据验证,我让你来决定。
我也试着这样覆盖实体
设置器。
...
/**
* Set myColumn
*
* @param string $myColumn
*
* @return myEntity
*/
public function setMyColumn($myColumn)
{
$this->myColumn = ($myColumn === null || $myColumn === '') ? 'myDefaultValue' : $myColumn;
return $this;
}
...
这一点,虽然看起来比较干净,但并不。
原因是邪恶的form->handleRequest()
方法并没有使用Model'的setter方法来更新数据(详见form->setData()
)。
我使用的解决方法是一个LifeCycleCallback
。我还在等着看是否有更多的"native"方法,例如`@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');
}
你也可以用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\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'
这些对我来说都没有用。 我在doctrine'的网站上找到了一些文档,说是直接设置值,设置一个默认值。
http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/faq.html
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");
通过这个答案,我鼓励你思考一下,为什么首先需要数据库中的默认值? 通常是为了允许创建非空约束的对象。
我也在努力解决同样的问题。 我想让数据库中的默认值进入实体(自动)。 你猜怎么着,我做到了:)
<?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";