【问题标题】:MySQL/Doctrine: allowing null fields on insert, but not updateMySQL/Doctrine:允许插入空字段,但不允许更新
【发布时间】:2020-02-07 00:10:59
【问题描述】:

有时需要创建具有一些未定义字段的实体,但要防止在后续更新中存储未定义值。例如,下面示例中的用户实体必须在解析“名称”字段的值之前进行持久化。创建后,只有在name字段不为空时才需要再次持久化。

/**
 * @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
}

使用空名称字段保留上述实体将导致“列不能为空”SQL 错误。理想情况下,会有两个单独的“NOT NULL ON INSERT”和“NOT NULL ON UPDATE”约束。由于情况并非如此,因此必须使用其他解决方案。

  • 一个简单的解决方案是从表中删除“非空”约束以允许空插入和
    在 PHP 端验证实体以防止在更新时设置空值。这种方法需要额外的努力和谨慎。
  • 另一种解决方案是定义非空默认值 代表“未定义”,如 $name=''、$birthday=new Date('1900-01-01')。但是这个 需要在使用它们之前将这些值转换为空 (例如,显示一个表单来设置实际名称和日期)。
  • 另一种解决方案是创建“EntityData”对象并添加
    可为空的 OneToOne 关系。这很酷,因为整个组而不是单个字段都放宽了 not null 约束。 但是,这需要为用户创建单独的表/实体
    身份及其内容。

关于如何最好地处理这些案例还有其他想法吗?

【问题讨论】:

标签: mysql doctrine-orm


【解决方案1】:

您可以使用学说 ORM 中的 preUpdate 事件来检查属性是否不同于 null。

        /** @PreUpdate */
     public function doStuffOnPreUpdate()
     {
            $this->value = 'changed from preUpdate callback!';
     }

您还必须考虑在实体上添加@HasLifecycleCallbacks 注释。 文档链接: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/events.html#lifecycle-events

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-17
    • 1970-01-01
    • 2023-04-10
    • 2015-10-04
    • 2016-07-15
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多