MySQL/Doctrine: 插入时允许空字段,但不允许更新
MySQL/Doctrine: allowing null fields on insert, but not update
有时需要创建一个包含一些未定义字段的实体,但要防止在后续更新时存储未定义的值。例如,下面示例中的用户实体必须在解析 'name' 字段的值之前持久化。一旦创建,只有当name字段不为null时,才应该再次持久化。
/**
* @ORM\Entity()
*/
class User
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id; //autoincrement
/**
* @ORM\Column(type="string")
*/
private $name; //null at the time of creation
/**
* @ORM\Column(type="date")
*/
private $birthday; //null at the time of creation
}
使用空名称字段保留上述实体将导致 'Column cannot be null' SQL 错误。理想情况下,会有两个单独的 "NOT NULL ON INSERT" 和 "NOT NULL ON UPDATE" 约束。由于情况并非如此,因此必须使用其他解决方案。
- 一个简单的解决方案是从 table 中删除 "not null" 约束以允许空插入和
在 PHP 端验证实体以防止在更新时设置空值。这种方法需要额外的努力和关注。
- 另一种解决方案是定义非空默认值
代表 'undefined',如 $name='', $birthday=new Date('1900-01-01')。但是这个
在使用它们之前需要将这些值转换为空
(例如,显示一个表格来设置实际的姓名和日期)。
- 另一种解决方案是创建 "EntityData" 对象并添加
可为空的 OneToOne 关系。这非常酷,因为对整个组而不是单个字段放宽了 not null 约束。
但是,这需要为 User
创建单独的 tables/entities
标识及其内容。
关于如何最好地处理这些情况还有其他想法吗?
您可以使用来自 doctrine ORM 的 preUpdate
事件来检查属性是否不同于 null。
/** @PreUpdate */
public function doStuffOnPreUpdate()
{
$this->value = 'changed from preUpdate callback!';
}
您还必须考虑在实体上添加 @HasLifecycleCallbacks
注释。
文档 link:
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/events.html#lifecycle-events
有时需要创建一个包含一些未定义字段的实体,但要防止在后续更新时存储未定义的值。例如,下面示例中的用户实体必须在解析 'name' 字段的值之前持久化。一旦创建,只有当name字段不为null时,才应该再次持久化。
/**
* @ORM\Entity()
*/
class User
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id; //autoincrement
/**
* @ORM\Column(type="string")
*/
private $name; //null at the time of creation
/**
* @ORM\Column(type="date")
*/
private $birthday; //null at the time of creation
}
使用空名称字段保留上述实体将导致 'Column cannot be null' SQL 错误。理想情况下,会有两个单独的 "NOT NULL ON INSERT" 和 "NOT NULL ON UPDATE" 约束。由于情况并非如此,因此必须使用其他解决方案。
- 一个简单的解决方案是从 table 中删除 "not null" 约束以允许空插入和
在 PHP 端验证实体以防止在更新时设置空值。这种方法需要额外的努力和关注。 - 另一种解决方案是定义非空默认值 代表 'undefined',如 $name='', $birthday=new Date('1900-01-01')。但是这个 在使用它们之前需要将这些值转换为空 (例如,显示一个表格来设置实际的姓名和日期)。
- 另一种解决方案是创建 "EntityData" 对象并添加
可为空的 OneToOne 关系。这非常酷,因为对整个组而不是单个字段放宽了 not null 约束。 但是,这需要为 User
创建单独的 tables/entities 标识及其内容。
关于如何最好地处理这些情况还有其他想法吗?
您可以使用来自 doctrine ORM 的 preUpdate
事件来检查属性是否不同于 null。
/** @PreUpdate */
public function doStuffOnPreUpdate()
{
$this->value = 'changed from preUpdate callback!';
}
您还必须考虑在实体上添加 @HasLifecycleCallbacks
注释。
文档 link:
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/events.html#lifecycle-events