davidmpeace/squirrel

Laravel 包,自动缓存和检索使用 Eloquent ORM 查询记录时返回的模型

0.6.2 2018-11-23 13:22 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:47:30 UTC


README

Squirrel 是一个 Eloquent 缓存解决方案,它可以为您处理 '记住' 和 '忘记' 的复杂性。此包旨在与 Laravel 一起使用。Squirrel 在使用 Eloquent ORM 查询记录时自动缓存和检索模型。当使用 Squirrel 时,您可以预期数据库查询的数量将大幅减少,并且可以确信您从缓存中永远不会检索到过时数据。

许可证

Squirrel 是开源软件,采用 MIT 许可证

安装

要开始使用 Squirrel,请将其添加到您的 composer.json 文件中作为依赖项

composer require davidmpeace/squirrel

基本用法

要使用 Squirrel 库,您只需为任何想要实现缓存的模型使用 Squirrel 特性即可。通常,您会希望将特性实现到您的基类中,以便所有子类都能自动继承此功能。

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;
use Eloquent\Cache\Squirrel;

class MyAppSuperModel extends Model
{
    use Squirrel;
}

就这样!您现在将自动继承 Squirrel 的所有魔法。

默认行为

在不进行任何自定义的情况下,Squirrel 的行为如下

  1. 每个模型将使用基 Eloquent 模型类中定义的 $model->getKeyName() 方法返回的键进行缓存。
  2. 使用 Squirrel 特性的所有模型都将“激活”缓存。
  3. 每个模型将在 24 小时后过期。

配置

有时您可能需要对每个模型进行自定义配置。以下是一些您可以实现以覆盖默认行为的方法的示例。

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;
use Eloquent\Cache\Squirrel;

class User extends Model
{
    use Squirrel;
    
    /**
     * Implement this method, to establish additional unique keys on your table.  Doing this gives Squirrel more power
     * in establishing more cacheable queries.  Return an array of string column names, or nested arrays for 
     * compound unique keys.
     */
    public function getUniqueKeys()
    {
        $primaryKey = $this->getKeyName();
        return [$primaryKey, 'uuid', ['account_id', 'email']];
    }
    
    /**
     * Implement this method to cacheing on or off for this model specifically.  Returning false on this method
     * does not affect other models also using Squirrel.
     */
    public function isCacheActive()
    {
        return true; 
    }
    
    /**
     * Implement this method to change the expiration minutes timeout when cacheing this model.
     */
    public function cacheExpirationMinutes()
    {
        return (60 * 24); 
    }
}

全局配置和方法

使用以下全局配置方法来更新实现 Squirrel 缓存的模型的所有设置。

use Eloquent\Cache\SquirrelCache;

SquirrelCache::setGlobalCacheActive(false);      // Turn Squirrel ON or OFF globally
SquirrelCache::isGlobalCacheActive();            // Returns the config value if Squirrel is active or not globally.
SquirrelCache::setCacheKeyPrefix("Squirrel::");  // Prefix used for all stored Cache Keys
SquirrelCache::getCacheKeyPrefix();              // Returns the cache key prefix
SquirrelCache::setLoggingActive(true);           // Turns on internally logging for cache hits\misses, and DB queries.
SquirrelCache::isLoggingActive();                // Returns true if logging is enabled.
SquirrelCache::getLogs();                        // Returns the array of logs that were generated so far from Squirrel.
SquirrelCache::getLogSummary();                  // Returns a simple log summary of hits, misses, and DB queries.
SquirrelCache::flushAll();                       // Flushes all cached models from Squirrel

Squirrel 模型实例方法

这些方法对任何使用 Squirrel 特性的对象都可用

$model->remember();                  // Will store the object in Cache
$model->forget();                    // Will remove the object from Cache
$model->isCached();                  // Returns true if the current object is stored in cache.
$model->isCacheing();                // Returns true if Cacheing is on for this model
$model->cachedData();                // Returns the data that is stored in cache for this object.
$model->cacheKeys();                 // Will return an array of all the Cache keys used to store the object
$model->primaryCacheKey();           // Will return the primary cache key for the object.
$model->cacheExpirationMinutes();    // Returns the number of minutes cache records stay available.
$model->countCachedWithSameClass();  // Returns the number of cached models with the same class.
$model->forgetAllWithSameClass();    // Forgets all cached models with the same class.

支持的查询

Squirrel 旨在支持多个唯一键以及复合唯一键,因此任何基于唯一键尝试检索单行数据的查询都将正常工作。但是,只要这是查询的唯一部分,您也可以执行 "In" 查询。以下是一个示例

// Simple ID Queries
Model::find(1);
Model::whereId(1)->get();

// This works because we return a compound unique key on the model
Model::whereAccountId(12)->whereEmail('foo@bar.com')->get();  

// Also works, because it will try to find all the individual records
Model::whereIn('id', [1,2,3,4,5])->get(); 

// Works if 'uuid' is returned as a unique key on the model
Model::whereUuid('12345-12346-123456-12356')->first(); 

// THESE QUERIES DO NOT WORK WITH CACHEING, AND WILL QUERY THE DB

// WON'T CACHE because the "=" equals sign, and "in", are the only supported operators.
Model::where('id', '>', 50)->get();

// WON'T CACHE because the field is not defined as a unique key on the model
Model::wherePlanId(23)->first();

内部原理

Squirrel 的工作原理是通过扩展默认的 \Illuminate\Database\Query\Builder 类,该类负责执行模型查询。

默认情况下,模型继承了一个名为 newBaseQueryBuilder() 的方法,该方法负责返回构建器对象。我们重载此方法,以便可以返回 SquirrelQueryBuilder 对象。

SquirrelQueryBuilder->get() 方法执行实际的查询。然而,在我们查询数据之前,我们首先检查我们的模型是否通过任何唯一键缓存,如果是,则返回它,否则进行查询。最后,查询执行后,我们将检索到的数据保存到缓存中,以便在数据过期之前不会再次访问。

缓存键以以下格式存储

SquirrelCache::$cacheKeyPrefix . "::" . get_class($model) . "::" . serialize(uniquekey);

对于 id=1 的用户模型的示例

Squirrel::App\\User::a:1:{s:2:"id";s:1:"1";}

对于 account_id=27 且 email=foo@bar.com 的用户模型的示例

Squirrel::App\\User::a:2:{s:10:"account_id";s:2:"27";s:5:"email";s:11:"foo@bar.com";}