Files
hyperf-admin/docs/backend/scaffold_entity.md
2020-06-19 16:42:33 +08:00

2.7 KiB

在脚手架一结中已经介绍, Controller中的module_class属性, 告诉了我们要操作的是 mysql的那张表, 那么如果当我们要管理的数据存储方式是elasticsearch, mongo, 甚至是三方服务的api时 , 该怎么办呢?

此时, 我们抽象出了一个实体entity的概念, 源码见这里, 实体接口如下

interface EntityInterface
{
    public function create(array $data);

    public function set($id, array $data);

    public function get($id);

    public function delete($id);

    public function count($where);

    public function list($where, $attr = [], $page = 1, $size = 20);

    public function getPk();

    public function isVersionEnable();
}

实体接口定义了要操作对象的CRUD等必备接口, 然后针对不同数据源封装了MysqlEntityAbstract, EsEntityAbstract, ApiEntityAbstract等抽象类, 脚手架控制器中增加了entity_class属性

比如, 我们有一个es 的索引goods存放商品数据

// es model
class EsGoods extend EsBaseModel
{
  // ....
}

// entity 
class EsGoodsEntity extend EsEntityAbstract
{
  // ....
}

// 将实体注入进脚手架
class GoodsController extend AdminAbstractController
{
  	public $entity_class = EsGoodsEntity::class;
}

如上操作, 我们将可以通过脚手架完成es数据的管理, 而且, 所有的页面效果, 搜索支持等几乎与mysql无异.

当然, 我们还可以继续简化以上操作

// es model
class EsGoods extend EsBaseModel
{
  // ....
}

// 将 model 注入进脚手架
class GoodsController extend AdminAbstractController
{
  	public $model_class = EsGoods::class;
}

(⊙o⊙)… $model_class 不是用来存放 mysql 模型名称的吗, 怎么放了 es 的 modle 名? 看如下源码

public function getEntity()
{
  if ($this->entity_class) {
    return make($this->entity_class);
  }
  if ($this->model_class && make($this->model_class) instanceof BaseModel) {
    return new class ($this->model_class) extends MysqlEntityAbstract {};
  }
  if ($this->model_class && make($this->model_class) instanceof EsBaseModel) {
    return new class ($this->model_class) extends EsEntityAbstract {};
  }

  return null;
}

我们通过匿名类的方式动态生成实体, 进一步简化了操作, 但脚手架最终使用的还是entity对象

通过以上形式的抽象, 我们可以实现ApiEntityAbstract, MongoEntityAbstract, RedisListEntityAbstract 等等任意可以操作的数据源了, 而且使用上跟之前完全一样. 将所有数据源上的区别都隐藏在***EntityAbstract 中.

看, 就是这么方便.