Laravel利用模型观察者处理缓存

还在为项目中缓存的管理而感到心累,操作DB后忘了清理缓存?缓存与DB不一致?等......话不多说先看思路

利用模型观察者Observer去监听模型更新、删除等操作,拿到当前操作模型,找出缓存key,删掉即可。原理很简单,下面看一下代码

先封装一个基础类

<?php

namespace App\Observers;

use Illuminate\Database\Eloquent\Model;

class Observer
{
    // 可监听的操作 creating created updating updated saving saved deleting deleted restoring restored

    /**
     * 当前操作模型
     *
     * @var Model
     */
    protected $model;

    /**
     * 获取所有的缓存key
     *
     * @return array
     */
    protected function getCacheKeys(): array
    {
        return [];
    }

    /**
     * 清理缓存
     *
     * @return int 删除数量
     */
    protected function clearCache(): int
    {
        $keys = $this->getCacheKeys();
        if ($keys === []) {
            return 0;
        }
        $redis = redis();
        $cacheKeys = [];
        foreach ($keys as $key) {
            // 如果是通配符,查一下所有的缓存key
            if (strpos($key, '*')) {
                $cacheKeys = array_merge($cacheKeys, $redis->keys($key));
            } else {
                $cacheKeys[] = $key;
            }
        }

        // 去重并删除缓存
        return $redis->del(array_unique($cacheKeys));
    }
}

定义一个GoodsSpu模型的观察者类GoodsSpuObserver.php 重点是getCacheKeys这个函数,配置好返回需要清理的缓存key,每个模型配置这个函数即可

<?php

namespace App\Observers;

use App\Common\RedisKey;
use App\Models\GoodsSpu;

class GoodsSpuObserver extends Observer
{
    public function saving(GoodsSpu $goodsSpu)
    {
        $this->model = $goodsSpu;

        parent::clearCache();
    }

    public function deleted(GoodsSpu $goodsSpu)
    {
        $this->model = $goodsSpu;

        parent::clearCache();
    }

    protected function getCacheKeys(): array
    {
        return [
            // 商品详情key
            sprintf(RedisKey::GOODS_DETAIL, $this->model->getAttribute('enterprise_id'), $this->model->getAttribute('id')),
        ];
    }
}

接着注册一下GoodsSpuObserver

App\Providers\AppServiceProvider中加入
// SPU表观察者
GoodsSpu::observe(new GoodsSpuObserver());

测试一下更新记录的时候缓存是不是会自动被刷掉

// 简单的更新一下记录
$goodsSpu = GoodsSpu::query()->where('id', '=', 1)->first();
$goodsSpu->update([
    'updated_at' => time()
]);

return 'success';

观察一下redis

image.png

结束

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 使用缓存是系统性能优化的第一黄金法则。 缓存的设计和使用对一个系统的性能至关重要,平时接触到项目无论多少也都会在某...
    刀刃丿阅读 1,354评论 0 6
  • 少年游 草 高观国 春风吹碧,春云映绿,晓梦入芳裀。软衬飞花,远连流水,一望隔香尘。 萋萋多少江南恨,翻忆翠罗裙。...
    五色浮元子_阅读 345评论 0 0
  • 【原文】 桃之夭夭,灼灼其华。之子于归,宜其室家。 桃之夭夭,有蕡有实。之子于归,宜其家室。 桃之夭夭,其叶蓁蓁。...
    仙泉阅读 1,402评论 0 1
  • 以前总听同事们说,等孩子上了一年级,辅导功课的时候鸡飞狗跳。听他们说的时候,也就是过过耳朵,没有放到心里去。今天孩...
    万花筒里看世界阅读 94评论 0 0