资讯专栏INFORMATION COLUMN

Laravel源码解析之Model

CloudwiseAPM / 627人阅读

摘要:根据单一责任开发原则来讲,在的开发过程中每个表都应建立一个对外服务和调用。类似于这样解析的数据操作分两种它们除了有各自的特色外,基本的数据操作都是通过调用方法去完成整个。内并没有太多的代码,大多都是处理数据库链接。

前言

提前预祝猿人们国庆快乐,吃好、喝好、玩好,我会在电视上看着你们。

根据单一责任开发原则来讲,在laravel的开发过程中每个表都应建立一个model对外服务和调用。类似于这样

namespace AppModels;
    
use IlluminateDatabaseEloquentModel;
    
class User extends Model
{
    protected $table = "users";
}
解析

Laravel的数据操作分两种

DB facade

Eloquent ORM

它们除了有各自的特色外,基本的数据操作都是通过 IlluminateDatabaseQueryBuilder 调用方法去完成整个SQL。你也可以帮Builder这个类作为整个SQL操作的基类。这个类涵盖了以下的操作方法(部分展示)

方法
public function select($columns = ["*"])
public function selectSub($query, $as)
public function selectRaw($expression, array $bindings = [])
public function fromSub($query, $as)
public function fromRaw($expression, $bindings = [])
public function addSelect($column)
public function distinct()
public function from($table)
public function join($table, $first, $operator = null, $second = null, $type = "inner", $where = false)
public function joinWhere($table, $first, $operator, $second, $type = "inner")
public function joinSub($query, $as, $first, $operator = null, $second = null, $type = "inner", $where = false)
public function leftJoin($table, $first, $operator = null, $second = null)
public function where($column, $operator = null, $value = null, $boolean = "and")
public function orWhere($column, $operator = null, $value = null)
public function whereRaw($sql, $bindings = [], $boolean = "and")
public function whereIn($column, $values, $boolean = "and", $not = false)
public function orWhereIn($column, $values)

可见有很多方法在中国laravel站或者官方文档上都没有体现,所以说就算要精通一款框架,不去看它的源码也是不行的。这个文件在你项目目录中的 vendor/laravel/framework/src/Illuminate/Database/Query 下,你可以自行去查看。

DB facade

正常情况下你可能会这样写一个操作

DB::table("user")->get();

这个操作首先经过laravel的门面指向文件,不过它并不在 app.php 中,而是通过内核直接加载,它在

IlluminateFoundationApplication -> registerCoreContainerAliases()

被注册。门面直接调用 IlluminateDatabaseDatabaseManager 类。

public function registerCoreContainerAliases()
{
        foreach ([
            ...
            "encrypter"            => [IlluminateEncryptionEncrypter::class, IlluminateContractsEncryptionEncrypter::class],
            "db"                   => [IlluminateDatabaseDatabaseManager::class],
            "db.connection"        => [IlluminateDatabaseConnection::class, IlluminateDatabaseConnectionInterface::class],
            "events"               => [IlluminateEventsDispatcher::class, IlluminateContractsEventsDispatcher::class],
            "files"                => [IlluminateFilesystemFilesystem::class],
            ....
        )
}

IlluminateDatabaseDatabaseManager 内并没有太多的代码,大多都是处理数据库链接。当你使用 DB::table()时,会通过

public function __call($method, $parameters)
{
    return $this->connection()->$method(...$parameters);
}

转发,调用的是 IlluminateDatabaseConnection ,用户处理 table() 方法,随后会通过 table() 方法指向 IlluminateDatabaseQuery 类,开头我们讲过这个类了,这里就不多说了,随后就是各种sql的拼接->执行sql->结束战斗

Eloquent ORM

Eloquent ORM 与DB facade 类似,首先每个 Eloquent ORM 都需要继承父类 IlluminateDatabaseEloquentModel
你大概会这样写

User::find(1)

父类是不存在这个方法的,它会通过

public static function __callStatic($method, $parameters)
{
    return (new static)->$method(...$parameters);
}

去转发请求调用。同理

User::get()

则是通过

public function __call($method, $parameters)
{
    if (in_array($method, ["increment", "decrement"])) {
        return $this->$method(...$parameters);
    }
        
    return $this->newQuery()->$method(...$parameters);
}

去调用,这个方法最终以 new Builder() 而告终,

public function newEloquentBuilder($query)
{
    return new Builder($query);
}

最后我们到了 IlluminateDatabaseEloquentBuilder 文件下,这个类中涵盖了ORM的基本操作,例如find , findOrFail 等等。如果你在代码用到了get方法,抱歉,这里没有,它依旧会通过__call 方法将你的请求转发到 IlluminateDatabaseQueryBuilder 类中

$this->query->{$method}(...$parameters);

至此就完成了整个数据操作。

致谢

感谢你看到这里,希望本篇文章可以帮助到你,谢谢

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/29464.html

相关文章

  • Laravel Eloquent Fill 方法解析

    摘要:上一次分析了中的模型事件与观察者模式这次来解析一下中的用的童鞋应该都知道方法是一个给实例赋值属性的方法让我们点开方法先看一看它的源码这里笔者所使用的版本为最新版为了方便阅读删除掉了注释首先可以看到会先去调用一个自身的方法让我们点开 上一次分析了 Laravel 中的模型事件与观察者模式,这次来解析一下 Eloquent 中的 fill 用 Laravel 的童鞋应该都知道,fill 方...

    skinner 评论0 收藏0
  • Laravel学习笔记Query Builder源码解析(上)

    摘要:说明本文主要学习模块的源码。这里,就已经得到了链接器实例了,该中还装着一个,下文在其使用时再聊下其具体连接逻辑。 说明:本文主要学习Laravel Database模块的Query Builder源码。实际上,Laravel通过Schema Builder来设计数据库,通过Query Builder来CURD数据库。Query Builder并不复杂或神秘,只是在PDO扩展的基础上又开...

    Steve_Wang_ 评论0 收藏0
  • Laravel 学习笔记 Query Builder 源码解析(下)

    摘要:,看下源码返回很容易知道返回值是,然后将该值存储在变量中,这时。看下的源码去除掉字符后为返回从源码中可知道返回值为,这时。 说明:本文主要学习下Query Builder编译Fluent Api为SQL的细节和执行SQL的过程。实际上,上一篇聊到了IlluminateDatabaseQueryBuilder这个非常重要的类,这个类含有三个主要的武器:MySqlConnection, M...

    qpal 评论0 收藏0
  • Laravel 依赖注入源码解析

    在 Laravel 的控制器的构造方法或者成员方法,都可以通过类型约束的方式使用依赖注入,如: public function store(Request $request) { //TODO } 这里 $request 参数就使用了类型约束,Request 是类型约束的类型,它是一个类:IlluminateHttpRequest. 本文研究 Laravel 的依赖注入原理,为什么这样定义...

    Donne 评论0 收藏0
  • Laravel学习笔记Seeder填充数据小技巧

    摘要:而且,与是一对多关系一个分类下有很多,一个只能归属于一个与是一对多关系一篇博客下有很多,一条只能归属于一篇与是多对多关系一篇有很多,一个下有很多。 说明:本文主要聊一聊Laravel测试数据填充器Seeder的小技巧,同时介绍下Laravel开发插件三件套,这三个插件挺好用哦。同时,作者会将开发过程中的一些截图和代码黏上去,提高阅读效率。 备注:在设计个人博客软件时,总会碰到有分类Ca...

    cgspine 评论0 收藏0

发表评论

0条评论

CloudwiseAPM

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<