[扩展推荐] Laravel-model-caching 自动缓存模型及关联数据

Laravel

https://github.com/GeneaLabs/laravel-model...

起因

我创建这个包是为了满足一个客户的需求,该项目具有复杂的嵌套表单,其中包含许多 <select>,导致在一个页面上有700多个数据库查询。我需要一个从模型中抽象缓存过程的包,可以缓存自定义查询以及缓存模型关系。本包试图满足这些需求。

特性

  • 自运行、自失效关系(仅在渴求式加载时)缓存。
  • 自运行、自失效模型查询缓存。
  • 支持使用缓存标签。

要求

  • PHP >= 7.1.3
  • Laravel 5.8

可能冲突的包

任何覆盖 Model 类中的 newEloquentModel() 方法的包都可能与此包冲突。 当然,任何实现自己的 Querybuilder 类的包都会有效地绕过这个包,使它们不兼容。

以下是我们认为可能不兼容的包:

当前无效事项

以下情形目前使用本包无效。

- 延迟加载关系缓存,见#127。当前延迟加载的从属关系(belongs-to relationships)被缓存。其他关联关系的缓存工作正在进行中。
- 在有 Eloquent  查询中使用 select() 子句,参见 #238 (在问题中讨论的变通方法)

Installation

请确保不需要此软件包的特定版本时,这样使用:

composer require genealabs/laravel-model-caching:*

更新说明

0.6.0

用于禁用此包的环境和配置项已更改。

  • 如果你之前已发布配置文件,请再次发布,并根据需要进行调整:

    php artisan modelCache:publish --config
  • 如果你在 .env 文件中禁用了包,请将 MODEL_CACHE_DISABLED 更改为 true

0.5.0

以下接口已更改(请参阅下面的相应部分):

  • 指定模型的缓存前缀

配置

推荐(可选)自定义缓存存储

如果你要使用与 Laravel 默认缓存存储不同的缓存存储,你可以通过将 .env 文件中的 MODEL_CACHE_STORE 环境变量设置为 config/cache.php 中配置的缓存存储的名称来实现(你可以根据你的特定需求定义任何自定义缓存存储)。

MODEL_CACHE_STORE=redis2

使用

为获得最佳性能,建议使用可标记的缓存存储(如 redis、memcached)。虽然这是可选的,但使用不可标记的缓存存储意味着每次创建、保存、更新或删除模型时都会清除整个缓存。

为了便于维护,我建议添加一个使用了 Cachable trait 的 BaseModel 模型,从中扩展所有其他的模型。 如果你不想这样做,只需直接从 CachedModel 扩展你的模型。

以下是 BaseModel 类的示例:

<?php namespace App;

use GeneaLabs\LaravelModelCaching\Traits\Cachable;

abstract class BaseModel
{
    use Cachable;
    //
}

多数据库连接

感谢 @dtvmedia 对这个特性的建议。这实际上是一个比 cache 前缀更健壮的解决方案

多个数据库连接会自动处理(译者注 确保不同连接缓存键前缀不一样)键独立。这对于多应用程序尤其重要,当然对于任何使用多个数据库连接的应用程序也是如此。

可选的缓存键前缀

感谢 @lucian-dragomir 推荐这个特性 !您可以使用缓存键前缀来为多个应用程序维护各自缓存条目。为此,建议将可缓存特性添加到基本模型中,然后在那里设置缓存键前缀配置值。

示例:

<?php namespace GeneaLabs\LaravelModelCaching\Tests\Fixtures;

use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class BaseModel extends Model
{
    use Cachable;

    protected $cachePrefix = "test-prefix";
}

还可以在配置文件为所有缓存的模型设置缓存前缀:

    'cache-prefix' => 'test-prefix',

例外: 用户模型

我不建议缓存用户模型,因为这是一种特殊情况,这是由于它扩展了 lighting \Foundation\Auth\User。重写它会破坏(既有)功能。不仅如此,缓存用户模型可能也不是一个好主意,因为您总是希望从中提取最新的信息。

实验特性: 在特定模型中使用缓存 Cool-down (冷却期)

在某些情况下,您可能希望添加缓存失效冷却期。例如,您可能有一个繁忙的站点,其中评论以很高的速率提交,并且您不希望每次提交的评论都使缓存失效。虽然我不推荐这样做,但您可以试验一下它的有效性。

要使用它,必须在模型(或基础模型,如果你想在多个或所有模型上使用它)中启用:

class MyModel extends Model
{
    use Cachable;

    protected $cacheCooldownSeconds = 300; // 单位秒 5 分钟

    // ...
}

之后可以在查询中(这样)实现:

(new Comment)
    ->withCacheCooldownSeconds(30) // 重写模型中默认的 cooldown ( 即属性$cacheCooldownSeconds)秒数
    ->get();

或:

(new Comment)
    ->withCacheCooldownSeconds() // 使用模型中默认的cooldown秒数 
    ->get();

禁用查询缓存

有两种方法可以禁用模型缓存:

  1. 在逐个查询实例中使用 ->disableCache()
  2. .env 文件中将 MODEL_CACHE_DISABLED 设为 true
  3. 如果你只需要为代码块或非 Eloquent 查询禁用缓存,这可能是更好的选择:

    $result = app("model-cache")->runDisabled(function () {
        return (new MyModel)->get(); // or any other stuff you need to run with model-caching disabled
    });

建议:在所有填充查询中使用 #1 选项,以避免在重新填充多次时提取了缓存信息。 你可以在链式查询中的任何位置使用 disableCache() 来禁用给定查询。 例如:

$results = $myModel->disableCache()->where('field', $value)->get();

手动刷新特定模型

你可以使用这条 Artisan 命令刷新特定模型的缓存:

php artisan modelCache:clear --model=App\Model

手动更新数据库时,这条命令就会排上用场。当 Laravel 应用之外的来源更新数据库后,也可以触发此操作。

总结

这就是你需要做的。现在缓存了所有模型查询和(关联)关系!!

在已经优化了一些页面的性能测试,高达900%! 大多数情况下,您应该看到性能提高了100%左右。

质量承诺

在包开发期,我尽可能地采用好的设计和开发实践,以确保这个包是最好的。我的软件包开发清单包括:

  • ✅ 实现尽可能接近100%的代码覆盖率进行单元测试。
  • ✅ 消除由Sensiolabs Insight 和 Scrunizer 发现的任何问题。
  • ✅ 完全兼容PSR1、PSR2 PSR4
  • ✅ 在 README.md 文件内包含详实文档。
  • ✅ 提供一个最新的 CHANGELOG.md 更新日志,日志遵从https://keepachangelog.com 规范。
  • ✅ 所有代码无 PHPMD 或 PHPCS 警告。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://genealabs.com/docs/laravel-model...

译文地址:https://learnku.com/laravel/t/33941

本帖已被设为精华帖!
本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 4

哇,这个不错哎

3年前 评论
seeker-x2y 2年前
playmaker

老版本 用不了吧

2年前 评论

9.x 好像不兼容

10个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!