【问题标题】:Persisting serialized object in Doctrine在 Doctrine 中持久化序列化对象
【发布时间】:2013-07-31 02:13:54
【问题描述】:

示例模型:

/** @Entity */
class Person{
    /**
     * @Id @Column(type="integer", nullable=false)
     * @GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /** @Column  */
    protected $name;

    /** @Column(type="datetime") */
    protected $created_at;

   //setters and getters...

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

我正在使用 json 在客户端/服务器之间进行通信。 我需要从客户端获取 json

{ "id": 123, "name": "john" }

并坚持,保持字段“created_at”不变。这样做:

$p = json_decode($string);
$person = new Person($p);
entity_manager->merge($person);
entity_manager->flush();

在这种情况下,对象已成功更新,但显然,“created_at”字段设置为“new DateTime”中的新值。 我可以从数据库中获取一个托管实体,然后只更改“名称”,但我不想要不必要的 Select..

简而言之,我该如何执行这样的操作:

UPDATE Person set name = "john" where id = 123

是否有注释可以在更新时忽略属性? 有没有办法将属性设置为不变?

编辑

在使用 SqlLogger 进行了几次测试后,我意识到方法 merge() 执行 SELECT 以获取当前状态... 所以,目前我的解决方案是自己获取对象并仅替换我想要更新的值。比如:

$std = json_decode($string);
$p = entity_manager->find('Person', $std->id);
$p->name = $std->name;
entity_managet->flush();

这种方式“选择”的数量是相同的,但我可以保留我没有从 json 获得的属性的原始值。

【问题讨论】:

    标签: php doctrine-orm doctrine


    【解决方案1】:

    Doctrine 需要一个持久化实体才能定义哪个字段已更新。

    http://apigen.juzna.cz/doc/doctrine/doctrine2.git/source-class-Doctrine.ORM.UnitOfWork.html#607-623

    如果您的问题仅与日期时间有关,您可以使用“Column”注释的“columnDefinition”部分来处理您的 create_at 值。

    http://docs.doctrine-project.org/en/2.0.x/reference/annotations-reference.html#annref-column

    以 mysql 为例:

    /** @Column(type="datetime", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP") */
    protected $created_at;
    
    //setters and getters...
    
    public function __construct($std){
        $this->id = $std->id;
        $this->nome = $std->nome;
        //And so remove this initialization
        //$this->created_at = new DateTime;
    }
    

    【讨论】:

    • 使用列定义的问题是CURRENT_TIMESTAMP标志被限制为每张表只有一列……你不能用它来自动设置创建的时间戳和最后更新的时间戳。
    • 我接受是因为第一句话很明显:“Doctrine 需要一个持久化的实体......”。这让我做了更多的测试,发现 merge() 也在 DB 中执行了一个选择。
    猜你喜欢
    • 2013-07-02
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    相关资源
    最近更新 更多