#1 楼
数据库默认值不受“便携式”支持。使用数据库默认值的唯一方法是通过columnDefinition
映射属性,在该属性中为字段映射到的列指定SQL
代码段(包括DEFAULT
原因)。您可以使用:
<?php
/**
* @Entity
*/
class myEntity {
/**
* @var string
*
* @Column(name="myColumn", type="string", length="50")
*/
private $myColumn = 'myDefaultValue';
...
}
首选PHP级别的默认值,因为这些值也可以在新创建和持久化的对象上正确使用(坚持新对象以获取默认值后,Doctrine将不会返回数据库。
评论
但是这里有一个问题:如果设置“日期时间”类型怎么办?
– artragis
2012年9月11日上午9:04
@artragis将实例化为实体构造函数
– Alain Tiemblo
2012-09-29 17:52
使用这种方法进行迁移时必须格外小心,因为任何现有的行都将导致迁移失败。
– Tamlyn
13-10-29在14:44
不要使用实例化区域来设置变量...相信我,不好的事情会发生。请改用构造函数区域。
– mimoralea
2014年9月4日15:08
我建议在注释中使用columnDefinition,否则有人将使用mysql客户端或phpmyadmin,并且值将是错误的...
– NDM
2015年5月4日14:09
#2 楼
<?php
/**
* @Entity
*/
class myEntity {
/**
* @var string
*
* @ORM\Column(name="myColumn", type="integer", options={"default" : 0})
*/
private $myColumn;
...
}
请注意,这使用SQL
DEFAULT
,某些字段(如BLOB
和TEXT
)不支持此SQL。评论
接得好!官方文档中似乎没有options = {“ default” = 0}选项
– WayFarer
2012年8月21日13:57
仅供参考,options参数对于无符号值也很有用。看到这个答案
–yvoyer
13年1月8日在18:55
我用这个和公认的答案来覆盖所有基础。还请注意,您也可以执行以下操作:options = {“ default”:0}请小心使用“而不是',因为它会导致我的学说版本出现错误。
– Scott Flack
2014年6月17日7:37
这应该是选定的答案!
– Eucel Eu Eu
2014年9月23日20:22在
@Matt他可能说过,因为它是一个未记录的功能,并且未保留的功能很容易被删除。正如现在所记录的那样,您应该放心使用它。
– jonathancardoso
2015年11月1日在18:50
#3 楼
在您的实体中设置构造函数,并在其中设置默认值。评论
当然,这似乎是合乎逻辑的方法。有没有人遇到在构造函数中设置默认值的问题?
– cantera
2011年11月1日,11:16
教义的推荐解决方案:doctrine-project.org/docs/orm/2.1/en/reference/faq.html
– cantera
2011年11月1日,11:16
@ cantera25应该是答案+1
– Phill Pafford
2012年12月12日在21:17
如果您添加需要具有默认值的新字段,则不会更新现有实体。因此,那不应该是答案。取决于您到底需要做什么
–TomášTibenský
16年5月4日在12:07
它也不会用于更新目的。不幸的是,如果只想清空字段(即使是整数),就可以返回默认值,那么它将无法正常工作。
– ThEBiShOp
16-09-20在8:18
#4 楼
使用:options={"default":"foo bar"}
而不是:
options={"default"="foo bar"}
例如:
/**
* @ORM\Column(name="foo", type="smallint", options={"default":0})
*/
private $foo
评论
对不起,你说得对。因此,您可以在此页面上找到说明:doctrine-orm注解参考
–斯坦尼斯拉夫·特列斯基(Stanislav Terletskyi)
16年5月26日在12:27
#5 楼
更新阅读Symfony文档的另一个原因永远不会过时。对于我的特定情况,有一个简单的解决方案,是将
field type
选项empty_data
设置为默认值。再次,此解决方案仅适用于表单中的空输入设置DB字段的情况。设为空。背景
以前的答案都没有帮助我解决我的特定情况,但是我找到了解决方案。
我有一个表单字段需要执行以下操作:
不需要,可以留空。 (使用'required'=> false)
如果留空,则应默认为给定值。为了获得更好的用户体验,我没有在输入字段上设置默认值,而是使用了html属性“ placeholder”,因为它不那么引人注目。
然后我尝试了此处给出的所有建议。让我列出它们:
为实体属性设置默认值:
<?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类,所有这些都不起作用,所有这些都有效。
IMPORTANT
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()
)。评论
此答案应该肯定会到达顶部。表单组件使用PropertyAccessor来获取和设置属性值。也许属性访问器应在可用时使用这些方法?
– Xobb
2014年8月11日下午13:36
布尔列不支持php的默认值,因此仅注释
–十字军
16 Dec 5'在8:34
当信息来自表单时,这是唯一有效的解决方案。我也不同意以上有关布尔值的评论。他们不接受默认注释。
– BernardA
17年11月1日在10:00
Symfony表单组件使用模型设置器,但仅当表单的模型格式数据与模型对象实例的相应getter返回的数据不同时才使用。如果您具有自定义的setter / getter方法-使用“ property_path”表单选项(将由PropertyAccessor处理)或自定义DataMapper(允许手动定义表单和模型对象之间的数据传输例程)。
–阿科麦拉(Arkemlar)
17年11月2日在16:36
这个问题是关于学说的,而不是关于symfony的,因此,这个答案并不是真正的话题。
– Omn
19-10-3在20:34
#6 楼
我使用的解决方法是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');
}
评论
对于未来的读者,不要依赖生命周期回调:)即使Marco Pivetta也反对它们。
– emix
19 Mar 9 '19 at 14:57
警告!如果实体已经设置了dtPosted属性,那么您的代码将简单地覆盖该属性。如果存在访问器,请始终使用它们!如果(!$ this-> getDtPosted()){$ this-> setDtPosted(new \ DateTime()); }
– Maxim Mandrik
19年3月29日在21:33
@emix可以解释吗?
– Erdal G.
20/12/3在20:29
#7 楼
您也可以使用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>
#8 楼
这是我为自己解决的方法。以下是带有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'
评论
在我的配置中使用这一行,Doctrine会在每次运行时尝试在列上删除默认值。 PHP应用程序/控制台学说:模式:更新
–变形器
13年6月3日,0:27
这是最糟糕的答案。 columnDefinition再次直接提出了具有ORM的目的,该ORM是从数据库中提取的。该解决方案将破坏可移植性,使您的软件依赖于数据库供应商,还将破坏Doctrine Migrations工具。
– Pedro Cordeiro
2014年2月25日14:30在
@PedroCordeiro我完全同意你的看法。这是一个快速的解决方案,直到出现另一个问题。
–普特纳
2014-2-27 15:40
#9 楼
在mysql数据库上对我也有效:Entity\Entity_name:
type: entity
table: table_name
fields:
field_name:
type: integer
nullable: true
options:
default: 1
评论
以感兴趣的注释格式:@ORM \ Column(name =“ Entity_name”,type =“ integer”,options = {“ default” =“ 1”})
–汉斯
16年3月3日在7:16
#10 楼
这些都不适合我。我在doctrine网站上找到了一些文档,说可以直接设置该值来设置默认值。https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/ reference / faq.html#how-can-i-add-default-values-to-a-column
private $default = 0;
这插入了我想要的值。
评论
请将链接更改为doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/…参见要点3.2.2。如何将默认值添加到列?
– Tobi
16年5月10日在8:16
正确的链接:教义v.2.6。参考。常问问题。如何将默认值添加到列?
– Maxim Mandrik
19年3月29日在21:02
#11 楼
添加到@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约束的对象。
#12 楼
如果您为实体使用yaml定义,以下内容在PostgreSQL数据库上对我有用:
Entity\Entity_name:
type: entity
table: table_name
fields:
field_name:
type: boolean
nullable: false
options:
default: false
评论
如果刷新前未使用$ entity-> setFieldName()怎么办?教义似乎将默认值定义为null。 yaml中唯一的解决方案是在实体类中定义默认值,这对我来说似乎是愚蠢的,因为它已在yaml中定义... -_-
– j0k
2015年3月10日13:42
#13 楼
尽管可以在构造函数中设置值,但使用Doctrine Lifecycle事件可能是更好的解决方案。通过利用
prePersist
Lifecycle Event,您可以仅在初始持久化时在实体上设置默认值。 评论
使用生命周期事件被视为黑客。永远不要依赖黑客。
– emix
16年8月18日在16:30
#14 楼
我也遇到同样的问题。我想将数据库的默认值自动添加到实体中。猜猜是什么,我做到了:)<?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";
评论
几年后再回到这一点,我建议您不要使用这种方法,它确实是一个hacky hack。
– Steffen Brem
16年11月11日13:56
由于您不建议自己回答,因此最好将其删除;)
– Dragos
19年1月22日在13:25
评论
@ORM \ Column(name =“ foo”,type =“ decimal”,precision = 7,scale = 2,options = {“ default” = 0})起作用(来自下面的不受欢迎的答案)@ORM \ Column(name =“ is_activated”,type =“ boolean”,options = {“默认”:0})或@ORM \ Column(name =“ is_activated”,type =“ boolean”,options = {“ default “ = 0})
Ahmed在Symfony 2.3中似乎不适用于布尔值。但是options = {“ default” =“ 0”})确实有效,将整数放在引号中。
如果是布尔值,为什么不使用:options = {“” default“:false}?