Eloquent 是否处理相关实体的缓存?

Does Eloquent handle caching of related entities?

我正在探索 Laravel 的 Eloquent 作为我项目当前的本地活动记录数据层的直接替代品。目前,我有一个 class User 支持与另一个 class、Group 的多对多关系。我当前的实现类似于:

class User {

    protected $_groups;  // An array of Group objects to which this User belongs

    public function __construct($properties = []){
        ...
    }

    public function groups() {
        if (isset($_groups))
            return $_groups;
        else
            return $_groups = fetchGroups();
    }

    private function fetchGroups() {
        // Lazily load the associated groups based on the `group_user` table
        ...
    }

    public function addGroup($group_id) {
        // Check that the group exists and that this User isn't already a member of the group.  If so, insert $group_id to $_groups.
        ...
    }

    public function removeGroup($group_id) {
        // Check that the User is already a member of the group.  If so, remove $group_id from $_groups.
        ...
    }

    public function fresh() {
        // Reload user and group membership from the database into this object.
        ...
    }

    public function store() {
        // Insert/update the user record in the `user` table, and insert/update/delete records in `group_user` based on the contents of `$_group_user`.
        ...
    }

    public function delete() {
        // If it exists, delete the user record from the `user` table, and delete all associated records in `group_user`.
        ...
    }
}

如你所见,我的 class:

  1. 执行相关组的延迟加载,在第一次查询后缓存;
  2. 维护 User 与其 Group 的关系的内部表示,仅在调用 store 时在数据库中更新;
  3. 在建立关系时执行完整性检查,确保 Group 存在并且在创建新关联之前尚未与 User 相关。

如果有任何这些事情,Eloquent 会自动为我处理吗?或者,我的设计是否存在某些 Eloquent 可以解决的缺陷?

您可以假定我将 User 重新实现为 User extends Illuminate\Database\Eloquent\Model 并使用 Eloquent 的 belongsToMany 替代我当前的 fetchGroups方法。

Eloquent 在内部缓存关系的结果,是的。您可以在 Model::getRelationValue() 方法中看到它的作用。

Eloquent也为大家提供了方法来帮助大家manage the many-to-many relationship。您可以在现有 API 中实现此功能。但是,这里有一些需要注意的事项:

  1. 当使用attach()detach()等时,查询会立即执行。调用 parent User::save() 方法只会保存 User 的详细信息,不会保存多对多关系信息。您可以通过临时存储传递给 API 的 ID 来解决此问题,然后在调用 User::store().

  2. 时对其进行操作
  3. 使用 attach/detach/etc 时不执行完整性检查。如果需要,最好将它们应用到您的 API 中。

  4. 添加或删除 ID to/from 多对多关系不会影响初始关系查询的缓存结果。您必须添加逻辑才能将相关模型插入或删除到集合中。

    例如,假设一个 User 有两个 Group。当我加载用户时,我可以使用 $user->groups 访问这些组。我现在在用户模型中缓存了一组组。如果我再次调用 $user->groups,它将返回这个缓存的集合。

    如果我使用 $user->detach($groupId) 删除一个组,将执行查询以更新连接 table,但 缓存的集合不会更改。添加组也是如此。