namespace App\Http\Controllers;
use App\Article;
class ArticleController extends Controller
{
public function index()
{
dd(Article::all());
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
}
/**
* Get all of the models from the database.
*
* @param array|mixed $columns
* @return \Illuminate\Database\Eloquent\Collection|static[]
*/
//从数据库表中获取所有模型
public static function all($columns = ['*'])
{
return (new static)->newQuery()->get(
is_array($columns) ? $columns : func_get_args()
);
}
/**
* Create a new Eloquent model instance.
*
* @param array $attributes
* @return void
*/
//这个类的构造函数
public function __construct(array $attributes = [])
{
$this->bootIfNotBooted();
$this->syncOriginal();
$this->fill($attributes);
}
/**
* Get a new query builder for the model's table.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
//针对模型类对应的数据表生成一个查询构造器
public function newQuery()
{
return $this->registerGlobalScopes($this->newQueryWithoutScopes());
}
/**
* Get a new query builder that doesn't have any global scopes.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
//获取查询构造器
public function newQueryWithoutScopes()
{
$builder = $this->newEloquentBuilder($this->newBaseQueryBuilder());
// Once we have the query builders, we will set the model instances so the
// builder can easily access any information it may need from the model
// while it is constructing and executing various queries against it.
return $builder->setModel($this)
->with($this->with)
->withCount($this->withCount);
}
/**
* Get a new query builder instance for the connection.
*获取针对一个连接的查询构造器
* @return \Illuminate\Database\Query\Builder
*/
//
protected function newBaseQueryBuilder()
{
$connection = $this->getConnection();
return new QueryBuilder(
$connection, $connection->getQueryGrammar(), $connection->getPostProcessor()
);
}
/**
* Get the database connection for the model.
* 通过模型类获取数据库连接
* @return \Illuminate\Database\Connection
*/
public function getConnection()
{
return static::resolveConnection($this->getConnectionName());
}
/**
* Resolve a connection instance.
* 获取一个连接实例
* @param string|null $connection
* @return \Illuminate\Database\Connection
*/
public static function resolveConnection($connection = null)
{
return static::$resolver->connection($connection);
}
这里的$resolver其实是Illuminate\Database\DatabaseManager,是Illuminate\Database\ConnectionResolverInterface接口的实例。
/**
* Get a database connection instance.
* 获取一个数据库连接的实例
* @param string $name
* @return \Illuminate\Database\Connection
*/
public function connection($name = null)
{
list($database, $type) = $this->parseConnectionName($name);
$name = $name ?: $database;
// If we haven't created this connection, we'll create it based on the config
// provided in the application. Once we've created the connections we will
// set the "fetch mode" for PDO which determines the query return types.
if (! isset($this->connections[$name])) {
$this->connections[$name] = $this->configure(
$this->makeConnection($database), $type
);
}
return $this->connections[$name];
}
/**
* Create a new Eloquent query builder for the model.
* 为模型创建一个新的Eloquent查询构造器
* @param \Illuminate\Database\Query\Builder $query
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function newEloquentBuilder($query)
{
return new Builder($query);
}
文件 \Illuminate\Database\Eloquent\Builder.php;
/**
* Create a new Eloquent query builder instance.
*
* @param \Illuminate\Database\Query\Builder $query
* @return void
*/
public function __construct(QueryBuilder $query)
{
$this->query = $query;
}
/**
* Set a model instance for the model being queried.
* 为查询构造器设置一个模型实例
* @param \Illuminate\Database\Eloquent\Model $model
* @return $this
*/
public function setModel(Model $model)
{
$this->model = $model;
$this->query->from($model->getTable());
return $this;
}
文件 \Illuminate\Database\Query\Builder.php;
/**
* Set the table which the query is targeting.
* 设置所要查询的数据表
* @param string $table
* @return $this
*/
public function from($table)
{
$this->from = $table;
return $this;
}
文件 \Illuminate\Database\Eloquent\Model.php;
/**
* Get the table associated with the model.
* 获取模型关联的数据表
* @return string
*/
public function getTable()
{
if (! isset($this->table)) {
return str_replace(
'\\', '', Str::snake(Str::plural(class_basename($this)))
);
}
return $this->table;
}
完成Eloquent查询构造器的实例化后,可以对数据库进行操作,下面来看Eloquent查询构造器中的方法实现的原理即"$instance->newQuery()->get($columns)"的get部分。
/**
* Execute the query as a "select" statement.
* 执行一个select查询语句
* @param array $columns
* @return \Illuminate\Database\Eloquent\Collection|static[]
*/
public function get($columns = ['*'])
{
$builder = $this->applyScopes();
// If we actually found models we will also eager load any relationships that
// have been specified as needing to be eager loaded, which will solve the
// n+1 query issue for the developers to avoid running a lot of queries.
if (count($models = $builder->getModels($columns)) > 0) {
$models = $builder->eagerLoadRelations($models);
}
return $builder->getModel()->newCollection($models);
}
接下来介绍Eloquent ORM是如何封装结果数据的,这部分是由hydrate()实现的。
文件 \Illuminate\Database\Eloquent\Builder.php;
/**
* Create a collection of models from plain arrays.
* 为数组创建一个模型类实例的集合
* @param array $items
* @return \Illuminate\Database\Eloquent\Collection
*/
public function hydrate(array $items)
{
$instance = $this->newModelInstance();
return $instance->newCollection(array_map(function ($item) use ($instance) {
return $instance->newFromBuilder($item);
}, $items));
}
/**
* Create a new model instance that is existing.
* 创建一个新的模型类实例
* @param array $attributes
* @param string|null $connection
* @return static
*/
public function newFromBuilder($attributes = [], $connection = null)
{
$model = $this->newInstance([], true);
$model->setRawAttributes((array) $attributes, true);
$model->setConnection($connection ?: $this->getConnectionName());
$model->fireModelEvent('retrieved', false);
return $model;
}
/**
* Set the array of model attributes. No checking is done.
* 通过数组设置模型类实例的attributes
* @param array $attributes
* @param bool $sync
* @return $this
*/
public function setRawAttributes(array $attributes, $sync = false)
{
$this->attributes = $attributes;
if ($sync) {
$this->syncOriginal();
}
return $this;
}
文件 \Illuminate\Database\Eloquent\Model.php;
/**
* Create a new Eloquent Collection instance.
* 创建一个新的Eloquent集合实例
* @param array $models
* @return \Illuminate\Database\Eloquent\Collection
*/
public function newCollection(array $models = [])
{
return new Collection($models);
}
文件\Illuminate\Support\Collection.php
/**
* Create a new collection.
* 创建一个\Illuminate\Support\Collection类实例
* @param mixed $items
* @return void
*/
public function __construct($items = [])
{
$this->items = $this->getArrayableItems($items);
}