【问题标题】:Doctrine and unrefreshed relationships教义和未更新的关系
【发布时间】:2011-06-16 15:54:13
【问题描述】:

我在 Doctrine (1.2.4) 中看到了意想不到的缓存效果。

我有几个由以下 YAML 定义的相关表(删除了示例中未使用的几个附加字段)。只是从学生到学校的简单的一对多关系。

School:
  tableName: tblschool
  columns:
    sch_id:
      name: sch_id as id
      primary: true
      autoincrement: true
      type: integer(4)
    sch_name:
      name: sch_name as name
      type: string(50)
Student:
  tableName: tblstudent
  columns:
    stu_id:
      name: stu_id as id
      primary: true
      autoincrement: true
      type: integer(4)
    stu_sch_id:
      name: stu_sch_id as school_id
      type: integer(4)
  relations:
    School:
      local: school_id
      foreign: id
      foreignAlias: Students

我可以创建一个简单的 Doctrine (1.2.4) 查询来找回一个学生

  $result1 = Doctrine_Query::create()
           ->from('Student s')
           ->where('s.id = 1')
           ->execute();

然后用

提取出对应的学校名称
foreach ($result1 as $result) { $ans[] = $result->School["name"]; }

我现在修改 school_id(导致关系),如下所示:

foreach ($result1 as $result) 
   { $result["school_id"] = 1 - $result["school_id"]; $result->save(); }

(我已经设置了数据库,以便提供另一个有效的学校 ID)。

如果我现在要立即尝试访问该关系,我将获得旧学校的名称。我理解这一点 - 这是因为我没有调用 refreshRelated()。我发现出乎意料的是,如果我立即进行另一个查询,重复第一个查询

  $result2 = Doctrine_Query::create()
           ->from('Student s')
           ->where('s.id = 1')
           ->execute();

得到结果

foreach ($result2 as $result) { $ans[] = $result->School["name"]; }

当我检查我的数组的内容时,我发现,在这两种情况下,我有相同的学校名称。换句话说,即使我已经进行了第二次查询并且正在查看查询结果,但关系并没有刷新。

数据库中的数据精细一致;即存在合适的学生和学校。例如。第二次运行上述序列 - 在不同的程序执行中 - 使用另一个学校名称(尽管再次重复)。

这个缓存是从哪里来的?

【问题讨论】:

    标签: php doctrine


    【解决方案1】:

    Doctrine 对关系使用了一点缓存:您的 Student->School 存储在 Student 属性中,而您的 Student->school_id 也存储在另一个属性中。

    当您更改 Student->school_id 时,数据库会被查询,Student->school_id 会更改,但 Student->School 不会更改,因为重新水化此对象可能会占用 CPU/内存。

    Doctrine 提供some method to refresh the relations,但使用它是开发人员的责任。

    例子:

    $student->refreshRelated('School'); //refreshes only the School relation
    $student->refreshRelated(); //refreshes every relation of the $student
    

    但是还有另一个缓存。 Doctrine 将所有水合对象保存在内存中,以限制请求数量。所以当你再次查询你的学生时,你会发现你的Student->School 没有改变。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多