Laravel使用模型访问器实现仅一次查询获取关联表gift列总和
解决方案
你可以通过访问器本地缓存+关联预加载的组合方案实现需求,完全不用改动原有$user->gift的调用逻辑,也不会重复触发查询:
第一步:先定义关联关系
首先在User模型中新增和礼品表的一对多关联:
// User.php public function gifts() { return $this->hasMany(Gift::class); // 替换为你自己的礼品表对应模型类名 }
第二步:编写带缓存的访问器
在访问器内增加本地缓存判断,已经计算过的总和直接返回,不用重复查库:
// User.php public function getGiftAttribute() { // 优先读取预加载的总和字段(批量查询场景用) if (isset($this->attributes['gift_sum'])) { return $this->attributes['gift_sum']; } // 单次查询场景:已经计算过就直接返回缓存结果 if (!isset($this->cached_gift_sum)) { $this->cached_gift_sum = $this->gifts()->sum('gift'); } return $this->cached_gift_sum; }
第三步(可选优化):批量查询时预加载总和
如果是查询用户列表的场景,你可以在查询用户时直接预加载所有用户的gift总和,全程只有2次查询(查用户+查所有用户的gift总和),不会出现N+1问题:
// 控制器查询代码 $users = User::withCount(['gifts as gift_sum' => fn($query) => $query->select(DB::raw('SUM(gift)'))])->get(); // 此时调用任意$user->gift都不会触发额外查询
新增礼品后的缓存刷新
如果用户领取了新的礼品,只需要清空对应缓存即可:
// 新增礼品记录后执行 unset($user->cached_gift_sum); unset($user->attributes['gift_sum']); // 之后再调用$user->gift会自动重新计算最新总和
内容的提问来源于stack exchange,提问作者kodfire
相关产品推荐
相关产品推荐

