OrzLee

这个世界上只有一个问题
那就是时间问题

实用-模型缓存trait

hascache.png

前言

好久没有写博客了,赖癌看来又发作了。也没有很高大上的东西写,就写写自己开发中比较顺手的小知识吧!

开发中经常会有些模型读取非常频繁,但是又很少做写入修改操作(类似于 分类、品牌等),这种情况缓存简直不能再好了,既可以大量减少数据库压力,又可以非常快速读取(前提要配置好缓存,比较推荐redis)。

Trait

如果你连trait都不认识的话好好看看文档吧。

起初最简单的思路就是能简单方便的让模型可以缓存和读取。laravel已经有了非常好用的缓存系统,非常方便,但是相对还可以封装一下,让模型缓存更加优雅。

代码非常简单,我就不多废话了:

namespace App\Traits\Model;

use Illuminate\Database\Eloquent\Collection;

trait HasCache
{
    protected $ttl;

    protected function tag(){
        return 'model_cache';
    }

    /**
     * @param null $key
     * @param \Closure|null $closure
     *
     * @return mixed|Collection
     */
    public static function cache($key = null, \Closure $closure = null){
        $model = new static();

        if($key instanceof \Closure){
            $closure = $key;
            $key = null;
        }

        return \Cache::tags($model->tag())->remember($key ?? get_class(),now()->addMinutes($model->getCacheTtl()),function () use ($closure, $model) {
            if($closure){
                return $closure($model);
            }
            return $model->get();
        });
    }
    //删除缓存
    public function forgetCache($key = null){
        return \Cache::tags($this->tag())->forget($key ?? get_class());
    }
    //设置缓存时间
    public function setCacheTtl($minutes){
        $this->ttl = $minutes;
        return $this;
    }

    public function getCacheTtl(){
        return $this->ttl ?: 60;
    }

使用

我这是使用的laravel-admin后台,有兴趣可以了解下,极大节约后台程序开发周期。

在需要缓存的模型中使用HasCachetrait:

class ProductCategory extends Model
{
    use SoftDeletes, ModelTree, AdminBuilder, HasCache;

    ...

    //也可以自己扩展缓存自己想要的数据
    public static function levelCache(){
        return self::cache(get_class().'level_cache', function ($model){
            $sort_closure = function ($query){
                $query->sort();
            };
            return $model->with(['children' => $sort_closure,'children.children' => $sort_closure])->where('parent_id',0)->sort()->get();
        });
    }
    //对应的删除缓存方法
    public static function forgetLevelCache(){
        return (new static())->forgetCache(get_class().'level_cache');
    }
}

后台控制缓存,在更新、添加数据后及时清除缓存,防止脏读,虽然是缓存但是还是要保证数据及时性吧!(例子中使用的是laravel-admin扩展

    /**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form()
    {
        $form = new Form(new ProductCategory);

        $form->display('id','ID');

        ...

        $form->saved(function (Form $form){
        //模型保存成功后的回调函数中删除缓存
            $form->model()->forgetLevelCache();
        });

        return $form;

如果没有使用laravel-admin,可以手动删除缓存或者监听模型保存成功事件,laravel-Eloquent:Events

平时使用:

ProductCategory::levelCache();
ProductCategory::setCacheTtl(30)->cache()
ProductCategory::cache(function(ProductCategory $model){
    ...
    return $model->get(); //返回你想保存的数据
})

结语

模型缓存后使用起来更加简单了,千万别把服务器内存玩爆了。开发中很多小技巧自己都没有好好总结,然后多了再总结就懒癌发作,哎!

本原创文章未经允许不得转载 | 当前页面:OrzLee » 实用-模型缓存trait

评论