laravel/lumen 数据库 和 Eloquent 浅析

一、 DatabaseServiceProvider 服务提供者

主要做了一下几件事:
– 初始化Model
– 注册Eloquent工厂
– 注册可队列化实体解析器实现
– 注册DB工厂
– 注册DB
– 注册DB连接

1、 初始化Model

主要清空初始化的类库和全局作用域。

2、 注册Eloquent工厂

作用暂未理解。
从代码中可以看到框架首先绑定了FakerGenerator::class数据伪造生成类,将其初始化到EloquentFactory中,并却传入了database_path('factories'),那么可以猜到大致作用为数据伪造器。

todo: 理解EloquentFactory

3、 注册可队列化实体解析器实现

用作暂时未理解。

todo: 理解QueueEntityResolver

4、 注册DB工厂

ConnectionFactory通过配置创建不同的的链接。
mysql为例,框架会通过MySqlConnector为我们创建一个数据库连接。MySqlConnector创建出来的其实就是PDO

另外,当我们开启主从分离的时候,ConnectionFactory还会根据相应的规则,创建读链接或者是写链接。

5、 注册DB

DatabaseManager负责管理ConnectionFactory创建出来的连接。
并且对外提供connection(创建)、purge(清除)、disconnect(断开)、reconnect(重连)方法,让外部进行统一调用。

6、注册DB连接

app('db.connection')后,返回一个有ConnectionFactory创建DatabaseManager负责管理的PDO连接。

Connection对外提供selectinsertupdatedeletecommitrollBackbeginTransaction等方法,提供对数据库的基本操作。

二、 Eloquent\ModelEloquent\BuilderQuery\BuilderSchema\Builder

Eloquent是框架提供的ORM

1、Eloquent\Model

Eloquent\Model是一个抽象类。模型必须继承它。Eloquent\Model类的主要作用,也是抽象类的主要作用是对子类所有功能的的一个抽象归纳。

主要抽象功能有:

  • 全局作用域管理,比如方法:addGlobalScopehasGlobalScopegetGlobalScopegetGlobalScopes等。
  • 事件管理,比如方法:observeflushEventListenersregisterModelEventgetObservableEventssetObservableEvents等。
  • 读写分离链接的主动选择,比如方法:ononWriteConnection
  • 关联关系管理,比如方法:hasOnemorphOnebelongsTomorphTohasManyhasManyThrough等。
  • 模型输入/输出数据管理,比如方法:guard系列方法(负责输入时过滤不想要的字段)、fill系列方法输入方法、getAttribute系列方法(负责输出时过滤敏感字段,格式化输出)
  • 数据操作方法,比如createupdatepushsavedestroydestroydelete等。这些方法提供了常用的数据库操作方法,并且在内部封装了事件机制。

个人感觉Eloquent\Model封装了比较多的东西,过于庞大,功能比较复杂,但是好处也是功能齐全,简便操作。可以更具自己要求是否开启Eloquent,为了简便开启Eloquent, 抑或是为了追求性能放弃Eloquent

2、Eloquent\Builder

Eloquent\Builder 在我看来才是真正的 Eloquent的核心, Eloquent\Model只是对其提供的方法进行封装和管理。

比如我们调用Model\User::first()方法,其实是通过Eloquent\Model__callStatic方法或者__call方法转发到了Eloquent\Builder上面。

我们需要注意到,通过Eloquent\Model每一次对数据的操作都会创建一个Eloquent\Builder。主要作用是一次请求封装在一个上下文中,我们可以很好的对其控制。好处有:

  1. 防止请求数据被污染
  2. 可以很好的管理内存

同理,http请求访问laravel\lumen框架,框架都会创建一个request也是为了如此。

还有一个细节需要注意的是Eloquent\Builder中的$passthru变量。Eloquent\Builder__call方法中,会判断如果请求放在存在于这个变量中的的时候,会返回Query\Builder,反之返回他自己Eloquent\Builder

3、 Query\Builder

Query\Builder 的作用就是存储本次数据库操作的基本操作。并且提供toSql方法,调用Query\Grammars\Grammar类来生成SQL语句。最后将SQL语句和绑定参数传给Connection类进行数据库操作。

Eloquent\Model在创建Eloquent\Builder的时候,会同时创建一个QueryBuilder,做一对一对于,所以QueryBuilder也可以很好的做好隔离工作。

4、 Schema\Builder

Schema\Builder是框架对数据库表操作的封装。

比如数据库的新增、修改、删除、索引、外键的管理等。

三、其他

1、 UML类图