0

0

Laravel Eloquent:高效统计每个分类下的文章数量

花韻仙語

花韻仙語

发布时间:2025-11-14 10:48:02

|

686人浏览过

|

来源于php中文网

原创

Laravel Eloquent:高效统计每个分类下的文章数量

本文将详细介绍如何在 laravel 8 中利用 eloquent orm 高效地统计每个分类下的文章数量。我们将从定义模型间的关联关系入手,逐步讲解如何使用 `withcount` 方法,从而避免手动编写复杂的 sql join 语句,以更优雅、可读性更强的方式实现数据聚合统计,并探讨其优势和使用场景。

在 Web 开发中,尤其是在构建内容管理系统(CMS)时,统计不同分类下相关内容的数量是一个非常常见的需求。例如,在一个博客系统中,我们可能需要显示每个文章分类下包含的文章总数。虽然可以通过 SQL 的 JOIN 和 GROUP BY 语句来实现,但在 Laravel 这样的框架中,利用其强大的 Eloquent ORM 可以以更简洁、更符合框架习惯的方式完成这项任务。

1. 场景描述与传统 SQL 方法回顾

假设我们有两个数据表:categories(分类)和 posts(文章)。

  • categories 表包含:id (主键), name (分类名称) 等字段。
  • posts 表包含:id (主键), category_id (外键,关联到 categories.id), title 等字段。

我们的目标是获取每个分类的名称以及该分类下对应的文章数量。

如果使用原生的 SQL 或 Laravel 的查询构造器(Query Builder),常见的实现方式如下:

SELECT
    c.name,
    COUNT(p.id) AS total_posts
FROM
    categories c
JOIN
    posts p ON c.id = p.category_id
GROUP BY
    c.id, c.name;

对应的 Laravel 查询构造器代码可能如下:

use Illuminate\Support\Facades\DB;

$categoriesWithCount = DB::table('categories')
    ->select('categories.name', DB::raw('count(posts.id) as total_posts'))
    ->join('posts', 'categories.id', '=', 'posts.category_id')
    ->groupBy('categories.id', 'categories.name')
    ->get();

// 结果示例:
// [
//     { "name": "技术", "total_posts": 15 },
//     { "name": "生活", "total_posts": 8 },
//     // ...
// ]

这种方法虽然有效,但在处理复杂的关联查询时,手动管理 JOIN 条件和 GROUP BY 字段会增加代码的复杂性和出错的可能性。Laravel Eloquent 提供了更优雅的解决方案。

2. 定义 Eloquent 模型及关系

首先,我们需要为 categories 表和 posts 表创建对应的 Eloquent 模型。

app/Models/Category.php:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    use HasFactory;

    protected $fillable = ['name'];

    /**
     * 一个分类可以有多个文章。
     */
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

app/Models/Post.php:

风易在线销售系统
风易在线销售系统

《风易在线销售系统》是一套为企业电子商务项目量身设计打造的在线商业销售系统,本系统将商品管理、客户管理、订单管理、信息管理、界面管理、系统管理等功能无缝融合,并且提供简单易用的后台管理平台,独家首创的模版内核系统,以及诸多实用的辅助模块。为客户提供了一个低成本,高效率,专业化的在线销售建设方案。 【新增】新增后台选择每页显示数据数量。 【新增】新增一个单客服模式功能。 【新增】新增根据一级分类显示

下载
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'category_id'];

    /**
     * 一篇文章属于一个分类。
     */
    public function category()
    {
        return $this->belongsTo(Category::class);
    }
}

在这里,我们在 Category 模型中定义了一个 posts() 方法,它返回 hasMany 关系,表示一个分类可以拥有多篇文章。这是实现统计的关键。

3. 使用 withCount 方法高效统计

定义好模型关系后,Laravel Eloquent 提供了一个非常方便且高效的方法 withCount() 来统计关联模型的数量。

use App\Models\Category;

$categoriesWithPostCount = Category::withCount('posts')->get();

// 遍历结果
foreach ($categoriesWithPostCount as $category) {
    echo "分类名称: " . $category->name . ", 文章数量: " . $category->posts_count . "\n";
}

代码解释:

  • Category::withCount('posts'):这会指示 Eloquent 在查询 categories 表时,同时对每个分类查询其关联的 posts 数量。
  • ->get():执行查询并获取所有结果。

结果结构:withCount 方法会在每个 Category 模型实例上添加一个名为 posts_count 的属性(默认情况下,关联方法名后加 _count),其中包含了该分类下文章的总数。

// 示例输出的 $categoriesWithPostCount 结构:
[
    {
        "id": 1,
        "name": "技术",
        "created_at": "...",
        "updated_at": "...",
        "posts_count": 15 // 这是 withCount 添加的属性
    },
    {
        "id": 2,
        "name": "生活",
        "created_at": "...",
        "updated_at": "...",
        "posts_count": 8
    },
    // ...
]

4. withCount 的优势与高级用法

优势:

  1. 代码简洁性: 无需手动编写复杂的 JOIN 和 GROUP BY 语句,大大简化了代码。
  2. 可读性: 通过方法名 withCount('posts') 即可清晰表达意图。
  3. 性能优化: Eloquent 会生成优化的 SQL 查询,通常会使用子查询或左连接来实现计数,避免了加载所有关联模型实例到内存中,提高了性能。
  4. 复用性: 关系一旦定义,可以在任何需要统计关联模型数量的地方使用 withCount。

高级用法:

  • 统计多个关联关系:

    $categories = Category::withCount(['posts', 'comments'])->get();
    // 此时每个 category 对象会有 posts_count 和 comments_count 属性
  • 自定义计数列名: 如果你不想使用默认的 关联名_count 作为属性名,可以传入一个数组:

    $categories = Category::withCount(['posts as total_articles'])->get();
    // 此时每个 category 对象会有 total_articles 属性
    echo $category->total_articles;
  • 对计数进行条件过滤: 你可以在 withCount 中添加闭包来对计数进行条件过滤,例如只统计已发布的文章:

    $categories = Category::withCount(['posts' => function ($query) {
        $query->where('published', true);
    }])->get();
    // 此时 posts_count 将只包含已发布的文章数量

总结

在 Laravel 中,当需要统计关联模型的数量时,强烈推荐使用 Eloquent 的 withCount 方法。它不仅能显著提高代码的简洁性和可读性,还能通过生成优化的 SQL 查询来保证良好的性能。通过正确定义模型间的关联关系,开发者可以充分利用 Eloquent ORM 的强大功能,更高效地处理数据查询和统计任务。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

340

2024.04.09

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

293

2024.04.09

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

772

2024.04.09

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

385

2024.04.10

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

141

2025.08.05

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

85

2025.08.05

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

80

2025.08.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

458

2026.03.04

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 13.4万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.3万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号