php - Doctrine 2 保留实体并从插入查询中排除空字段

标签 php mysql symfony doctrine-orm doctrine

我正在尝试向我的所有 Doctrine 生成的实体添加两个字段来处理日期(date_created 和 date_modified)。

请查看当前的 yml 以供引用

`Project\PasswordRecovery:
type: entity
table: PasswordRecovery
lifecycleCallbacks:
  prePersist: [ prePersist ]
indexes:
    fk_PasswordRecovery_User_idx:
        columns:
            - user_id
id:
    id:
        type: integer
        generator:
            strategy: AUTO
fields:
    date_created:
        type: datetime
        nullable: false
        columnDefinition: 'TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP'
        options:
            default: CURRENT_TIMESTAMP
    date_modified:
        type: datetime
        nullable: false
        columnDefinition: 'TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'
        options:
            default: CURRENT_TIMESTAMP
    token:
        type: text
        nullable: true
    user_id:
        type: integer
        nullable: true
manyToOne:
    users:
        targetEntity: User
        inversedBy: passwordRecoveries
        joinColumn:
            name: user_id
            referencedColumnName: id

我的问题:

正如您在下面的sql表CREATE信息中看到的那样,MYSQL可以在插入或更新查询时正确处理当前时间戳。

CREATE TABLE `PasswordRecovery` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `date_created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `date_modified` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `token` longtext COLLATE utf8_unicode_ci,
  PRIMARY KEY (`id`),
  KEY `fk_PasswordRecovery_User_idx` (`user_id`),
  CONSTRAINT `FK_41CD3A90A76ED395` FOREIGN KEY (`user_id`) REFERENCES `User` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `PasswordRecovery` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `date_created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `date_modified` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `token` longtext COLLATE utf8_unicode_ci,
  PRIMARY KEY (`id`),
  KEY `fk_PasswordRecovery_User_idx` (`user_id`),
  CONSTRAINT `FK_41CD3A90A76ED395` FOREIGN KEY (`user_id`) REFERENCES `User` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

但是,当持久化上面的实体时,即使我在持久化时强制将 $date_created 和 $date_modified 设置为 null,生成的查询在任何情况下都将包含这两个字段。 这会导致覆盖 sql DEFAULT 和 ON UPDATE 值。

首先,我将这些值强制设置为 NULL 以覆盖 CURRENT_TIMESTAMP 默认值,该默认值是由 Doctrine 中的日期时间类型强加的默认值。

$entity->setDateCreated(null);
$entity->setDateModified(null);

然后在设置剩余值后我坚持:

$em->persist($entity);
$em->flush();

通过使用 Doctrine 的 DebugStack 记录查询,我获得以下信息:

Array
(
    [1] => Array
        (
            [sql] => "START TRANSACTION"
            [params] => 
            [types] => 
            [executionMS] => 0.000178098678589
        )

    [2] => Array
        (
            [sql] => INSERT INTO PasswordRecovery (date_created, date_modified, token, user_id) VALUES (?, ?, ?, ?)
            [params] => Array
                (
                    [1] => 
                    [2] => 
                    [3] => stackoverflow test insert
                    [4] => 14
                )

            [types] => Array
                (
                    [1] => datetime
                    [2] => datetime
                    [3] => text
                    [4] => integer
                )

            [executionMS] => 0.00274181365967
        )

    [3] => Array
        (
            [sql] => "COMMIT"
            [params] => 
            [types] => 
            [executionMS] => 0.000401973724365
        )

)

来自数据库的作为 INSERT 语句的 SQL 结果:

INSERT INTO `PasswordRecovery` (`id`, `user_id`, `date_created`, `date_modified`, `token`)
VALUES
    (21, 14, NULL, NULL, 'stackoverflow test insert');

预期结果:

INSERT INTO `PasswordRecovery` (`id`, `user_id`, `date_created`, `date_modified`, `token`)
VALUES
    (23, 14, '2017-02-23 08:28:23', '2017-02-23 08:28:23', 'stackoverflow test insert');

到目前为止,我还没有找到一种方法来根据某些条件或数据跳过插入字段。将 'nullabe' 设置为 false 或 true 似乎没有任何区别。

使用查询生成器不是一个选项,因为 EntityManager 持久性方案深深 Root 于我正在使用的系统中。

对于这个特定项目来说,在 mysql 中使用日期时间也不是一个选项。

我见过关于日期管理的类似线程,但在这种情况下问题仅涉及这样一个事实:我无法完全让 MYSQL 负责生成和更新这两个日期字段,因为坚持/刷新 Doctrine 将始终存在使用生成的 INSERT 语句覆盖它们。

我正在研究生命周期回调,看看它们是否有助于不根据多个参数插入某些特定字段。

下一步将摆弄 orm 源。

希望有人能帮忙解决以上问题!

最佳答案

为了跳过插入 null 值而配置 doctrine 并不是一个好主意。在某些情况下,您可能需要数据库中的 null 值。

您可能应该在Entity中设置默认值,即在构造函数中。当您提供默认值时。当setters未提供这些值时,Doctrine将自动获取这些值。

对于当前示例:您应该具有以下内容:

public function __construct()
{
    $this->created_at = new \DateTime();
}

我在这种方法中从未遇到过任何问题。

希望这有帮助!

关于php - Doctrine 2 保留实体并从插入查询中排除空字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42410655/

相关文章:

php - 为什么 SOAP 参数的顺序在 PHP SOAP 中很重要,以及如何修复它?

php - 从 MySQL 中双选数据

mysql - 在 WHERE 子句中使用聚合函数来更新表

mysql - 使用Mysql lower_case_table_names 为1

symfony - 您可以在同一实体的不同索引中定义两个或多个类型吗?

PHP 主机名绑定(bind)

使用最近邻插值调整 PHP 图像大小?

php - 检查用户以html形式输入的数据是否已存在于php的数据库中

javascript - React - 使用和加载视频文件

session - 原则 2/多步骤表单/实体进入 session