Cipta kunci yang berbeza untuk cache pertanyaan dalam Laravel
P粉739886290
P粉739886290 2024-03-19 18:16:10
0
2
438

Saya menggunakan repositori dalam projek untuk cache semua pertanyaan.

Terdapat BaseRepository.

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;

class BaseRepository implements BaseRepositoryInterface{
    protected $model;
    protected int $cacheDuration = 600; //per seconds
    public function __construct(Model $model)
    {
        return $this->model = $model;
    }

    public function paginate(int $paginate,string $cacheKey)
    {
        return Cache::remember($cacheKey,$this->cacheDuration , function () use ($paginate) {
            return $this->model->latest()->paginate($paginate);
        });
    }
    // other methods ...
}

Kemudian saya menggunakan repositori ini dalam perkhidmatan saya

Perkhidmatan Pos:

use Illuminate\Support\Facades\App;

class PostService{
    public PostRepositoryInterface $postRepository;

    public function __construct()
    {
        $this->postRepository = App::make(PostRepositoryInterface::class);
    }
    public function paginate(int $paginate, string $cacheKey)
    {
        return $this->postRepository->paginate($paginate,$cacheKey);
    }
}

Akhirnya saya menggunakan PostService dalam pengawal

Pengawal belakang:

class PostController extends Controller{

    public PostService $postService;
    public function __construct()
    {
        $this->postService = App::make(PostService::class);
    }

    public function index()
    {
        string $cacheKey = "posts.paginate";
        return $this->postService->paginate(10);
    }
}

kaedah indeks akan mengembalikan 10 rekod terbaharu pertama dengan betul. Sekarang saya perlu mencipta CacheKey yang unik untuk semua pertanyaan repositori. Contohnya

TableName concat FunctionName // posts.paginate

Jadi saya boleh menggunakan kod ini dalam semua kaedah repositori

public function paginate(int $paginate)
{
    $cacheKey = $this->model->getTable().__FUNCTION__;
    return Cache::remember($cacheKey,$this->cacheDuration , function () use ($paginate) {
        return $this->model->latest()->paginate($paginate);
    });
}

Ini bagus. Tetapi masalahnya ialah kod ini diulang dalam semua kaedah kelas. Jika saya menggunakan kod ini dalam kelas lain, nama kaedah akan menjadi salah. Adakah anda mempunyai sebarang cadangan untuk mengelakkan pertindihan kod ini?

P粉739886290
P粉739886290

membalas semua(2)
P粉401901266

Saya menyelesaikan masalah ini dengan menghantar nama fungsi ke kelas lain

Saya mencipta kelas CacheKey:

class CacheKey{

    public static function generate(Model $model, $functionName):string
    {
        return $model->getTable()."_".$functionName;
    }
}

Kemudian dalam mana-mana kaedah repositori kita boleh menggunakan kelas pembantu ini seperti ini:

$cacheKey = CacheKey::generate($this->model,__FUNCTION__);
P粉287726308

Anda boleh menggunakan kaedah ajaib dengan cara ini:

class CacheService {
    private const $cacheableMethods = ['paginate'];
    private $otherSerivce;
    public __construct($otherSerivce) {
       $this->otherSerivce = $otherSerivce;
    }

    public __get($method, $args) {
        if(!in_array($method, static::$cachableMethods)) {
          return $this->otherSerivce->{$method}(...$args);
        }

        return Cache::remember(implode([$method, ...$args], ':'), function () {
            return $this->otherSerivce->{$method}(...$args);
        });
    }

}
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan