需求场景:
一些基本数据,比如分类这一数据,常常是只在项目定义初才会执行比较多的添加,修改,删除操作,在正式使用时,改动数据是相对少的情况,但查询分类数据的情况又是很多的,此种情况下,就可以使用缓存,将分类数据存入缓存中,大大减少了查询的时间
使用:
在thinkphp文档的链式操作中,有cache的使用方法:
Db::table('user')->where('id',5)->cache(true)->find();
但上方的方法在使用时,会存在一个问题,由于分类数据大多是多级的,最终在查询时以树形结构返回,此时使用该方法时,就会出现问题:返回的分类数据只会是最顶级的分类,再往下的子分类则不会显示。
解决方法:
1.可以先定义一个该分类的缓存类,并继承缓存基类BaseCache :
class QuestionbankCategoryCache extends BaseCache
2.设置缓存标识和缓存时间
// 缓存标识 (缓存标识可以使用创建枚举类并引用) protected $tagName = "QUESTIONBANK_CATEGORY_TAG"; // 缓存时间 public int $expire = 86400;
3.定义获取缓存和设置缓存的方法
//获取缓存数据 public function getQuestionbankCategory() { $data = $this->get($this->tagName); if($data) { return $data; } return false; }
//设置缓存数据 public function setQuestionbankCategory($data, $expire) { $this->set($this->tagName, $data, $expire); }
4.在逻辑类中获取和设置缓存
//分类列表数据 public function listTree():array { //创建缓存对象 $cache = new QuestionbankCategoryCache(); //获取缓存数据 $cacheData = $cache->getQuestionbankCategory(); if (!empty($cacheData)) { //查看缓存中是否具有数据,有则直接返回缓存的数据 return $cacheData; } //没有缓存数据则进行查询 $lists = QuestionbankCategory::field('id,name,sort,create_time,pid,topic_count') ->select() ->toArray(); //构建树形结构 $treeLists = buildCategoryTree($lists); //传入数据和缓存时间,写入缓存 $cache->setQuestionbankCategory($treeLists,$cache->expire); //返回缓存的数据 return $treeLists; }
5.需要注意的是,在添加,修改或删除操作中,都需要将缓存删除,否则数据将没有统一性
例如:
//编辑操作 public function edit($params) { try { $questionbankCategory = QuestionbankCategory::find($params['id']); if (!$questionbankCategory) { throw new LogicException('该题库分类不存在'); } QuestionbankCategory::update([ 'name' => $params['name'], 'sort' => $params['sort'] ?? 0, 'id'=>$params['id'] ]); // 删除缓存 $cache = new QuestionbankCategoryCache(); $cache->deleteTag(); } catch (\Exception $e) { throw new LogicException($e->getMessage()); } }
需要在执行完操作后,将缓存删除:
$cache = new QuestionbankCategoryCache(); $cache->deleteTag();
由于在创建缓存类的时候继承了BaseCache,所以可以直接调用deleteTag()方法清除缓存,在下次查询时,因为添加了缓存的判断,所以在缓存被删除后,将执行查询数据库的操作,然后再存入缓存中