Added Model::findFromCache and Model::findManyFromCache

This commit is contained in:
李铭昕 2019-01-25 14:38:31 +08:00
parent 194b66faa7
commit 4ae00df299
3 changed files with 71 additions and 8 deletions

View File

@ -26,5 +26,9 @@ trait Cacheable
public static function findManyFromCache($ids)
{
$container = ApplicationContext::getContainer();
$manager = $container->get(Manager::class);
return $manager->findManyFromCache($ids, static::class);
}
}

View File

@ -43,7 +43,9 @@ class RedisHandler implements HandlerInterface
protected $luaSha = '';
protected $defaultHash = ['HF-DATA' => 'DEFAULT'];
protected $defaultKey = 'HF-DATA';
protected $defaultValue = 'DEFAULT';
public function __construct(ContainerInterface $container, Config $config)
{
@ -64,8 +66,10 @@ class RedisHandler implements HandlerInterface
return $default;
}
if ($data == $this->defaultHash) {
return $default;
unset($data[$this->defaultKey]);
if (empty($data)) {
return [];
}
return $data;
@ -81,7 +85,7 @@ class RedisHandler implements HandlerInterface
throw new CacheException(sprintf('The value must is array.'));
}
$data = array_merge($data, $this->defaultHash);
$data = array_merge($data, [$this->defaultKey => $this->defaultValue]);
$res = $this->redis->hMSet($key, $data);
if ($ttl && $ttl > 0) {
$this->redis->expire($key, $ttl);
@ -113,22 +117,30 @@ class RedisHandler implements HandlerInterface
$list = $this->redis->eval($script, $keys, count($keys));
}
return $list;
$result = [];
foreach ($this->multiple->parseResponse($list) as $item) {
unset($item[$this->defaultKey]);
if ($item) {
$result[] = $item;
}
}
return $result;
}
public function setMultiple($values, $ttl = null)
{
// TODO: Implement setMultiple() method.
throw new CacheException('Method setMultiple is forbidden.');
}
public function deleteMultiple($keys)
{
// TODO: Implement deleteMultiple() method.
$this->redis->delete(...$keys);
}
public function has($key)
{
// TODO: Implement has() method.
return (bool) $this->redis->exists($key);
}
public function getConfig(): Config

View File

@ -86,6 +86,53 @@ class Manager
public function findManyFromCache(array $ids, string $class)
{
/** @var Model $instance */
$instance = new $class();
$name = $instance->getConnectionName();
$primaryKey = $instance->getKeyName();
if ($handler = $this->handlers[$name] ?? null) {
$keys = [];
foreach ($ids as $id) {
$keys[] = $this->getCacheKey($id, $instance, $handler->getConfig());
}
$data = $handler->getMultiple($keys);
$result = [];
$fetchIds = [];
if ($data) {
foreach ($data as $item) {
if (isset($item[$primaryKey])) {
$result[] = $item;
$fetchIds[] = $item[$primaryKey];
}
}
}
// 验证缺少哪些实体
$targetIds = array_diff($ids, $fetchIds);
$models = $instance->newQuery()->whereIn($primaryKey, $targetIds)->get();
/** @var Model $model */
foreach ($models as $model) {
$id = $model->getKey();
unset($targetIds['id']);
$key = $this->getCacheKey($id, $instance, $handler->getConfig());
$handler->set($key, $model->toArray());
}
foreach ($targetIds as $id) {
$key = $this->getCacheKey($id, $instance, $handler->getConfig());
$handler->set($key, []);
}
$result = array_merge($result, $models->toArray());
return $instance->hydrate($result);
}
$this->logger->warning('Cache handler not exist, fetch data from database.');
return $instance->newQuery()->where($primaryKey, '=', $id)->first();
}
protected function getCacheKey($id, Model $model, Config $config)