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:
- 执行相关组的延迟加载,在第一次查询后缓存;
- 维护
User
与其 Group
的关系的内部表示,仅在调用 store
时在数据库中更新;
- 在建立关系时执行完整性检查,确保
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 中实现此功能。但是,这里有一些需要注意的事项:
当使用attach()
、detach()
等时,查询会立即执行。调用 parent User::save()
方法只会保存 User 的详细信息,不会保存多对多关系信息。您可以通过临时存储传递给 API 的 ID 来解决此问题,然后在调用 User::store()
.
时对其进行操作
使用 attach/detach/etc 时不执行完整性检查。如果需要,最好将它们应用到您的 API 中。
添加或删除 ID to/from 多对多关系不会影响初始关系查询的缓存结果。您必须添加逻辑才能将相关模型插入或删除到集合中。
例如,假设一个 User
有两个 Group
。当我加载用户时,我可以使用 $user->groups
访问这些组。我现在在用户模型中缓存了一组组。如果我再次调用 $user->groups
,它将返回这个缓存的集合。
如果我使用 $user->detach($groupId)
删除一个组,将执行查询以更新连接 table,但 缓存的集合不会更改。添加组也是如此。
我正在探索 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:
- 执行相关组的延迟加载,在第一次查询后缓存;
- 维护
User
与其Group
的关系的内部表示,仅在调用store
时在数据库中更新; - 在建立关系时执行完整性检查,确保
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 中实现此功能。但是,这里有一些需要注意的事项:
当使用
attach()
、detach()
等时,查询会立即执行。调用 parentUser::save()
方法只会保存 User 的详细信息,不会保存多对多关系信息。您可以通过临时存储传递给 API 的 ID 来解决此问题,然后在调用User::store()
. 时对其进行操作
使用 attach/detach/etc 时不执行完整性检查。如果需要,最好将它们应用到您的 API 中。
添加或删除 ID to/from 多对多关系不会影响初始关系查询的缓存结果。您必须添加逻辑才能将相关模型插入或删除到集合中。
例如,假设一个
User
有两个Group
。当我加载用户时,我可以使用$user->groups
访问这些组。我现在在用户模型中缓存了一组组。如果我再次调用$user->groups
,它将返回这个缓存的集合。如果我使用
$user->detach($groupId)
删除一个组,将执行查询以更新连接 table,但 缓存的集合不会更改。添加组也是如此。