Laravel Eloquent ORM 教程:Eloquent 之旅第一部分

Laravel

Laravel 是优雅的 PHP Web 开发框架。具有高效、简洁、富于表达力等优点。采用 MVC 设计,是崇尚开发效率的全栈框架。是最受关注的 PHP 框架。

Eloquent ORM 内置在 Laravel 中,用于应用程序与数据库的交互。当你需要操作多种类型的数据库的时候,他提供了一种简单的封装,让你可以更简单的操作多种数据库,你只需要把你的查询语句写好,剩下的就交给 Eloquent ORM 吧!

我来举个例子解释一下我之前谈到的。假设你现在已经创建好一个laravel项目了,并且项目的config/database.php中数据库类型也是正确的,在开箱即用的情况下,laravel默认使用MySQL,因此我们将在这篇文章中使用Mysql。

'default' => env('DB_CONNECTION', 'mysql')

数据库连接的数组配置中:

'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

假设我们要创建一个博客平台,我们希望在数据库中有以下表(实体):

1.用户
2.岗位
3.评论
4.回复

Laravel开箱即用为我们提供了用户模型和create_users_table迁移文件,该文件位于我们项目的database/migrations文件夹下(迁移是Laravel用于创建我们的数据库结构的PHP文件)。这里的用户模型表示我们项目的用户表中的一个实体。让我们看看app/文件夹中的用户模型是什么样的。

//User.php

<?php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     *  字段白名单,设置该属性后,不在白名单的字段无法写入。
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     *  隐藏字段,设置该属性后,属性中的值将不会出现在你的查询结果中。
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     *  类型的转换,属性中的值将被自动转换为目标类型,支持的类型 integer, real, float, double, decimal:<digits>, string, boolean, object, array, collection, date, datetime, 和 timestamp
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

通过代码可以看到 User 模型继承了 Authenticatable(Illuminate\Foundation\Auth\User )类,该类继承了 Model 类,并实现了一系列接口。下面是 Authenticatable(Illuminate\Foundation\Auth\User )类代码:

//Illuminate\Foundation\Auth\User.php

<?php

namespace Illuminate\Foundation\Auth;

use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\MustVerifyEmail;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\Access\Authorizable;

class User extends Model implements
    AuthenticatableContract,
    AuthorizableContract,
    CanResetPasswordContract
{
    use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;
}

现在让我们把重点放到 Model 类的核心 Eloquent ORM 上来。

Alt Text

想要使用 Eloquent ORM 你需要继承 Illuminate\Database\Eloquent\Model 类,该类封装了一些数据库交互的基础操作。你可以通过以下命令创建 模型(model) 和 迁移(migration)。

$ php artisan make:model Post -m
Model created successfully.
Created Migration: 2020_01_07_015353_create_posts_table

此处参数 -m 的作用是在创建 Post 模型(model)的时候同时创建迁移(migration)。下面是我们通过上面命令创建的模型(model)。

//Post.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

可以看到该模型继承了 Illuminate\Database\Eloquent\Model 类, 这样你就可以使用 Eloquent ORM 的所有操作了!

属性 Protected $table

如果你的数据表名字和模型名称不一样,你可以通过设置该属性来自定义该模型关联的数据表;

protected $table = 'app_posts'; // 此处填写你的实际数据表名称

属性 Protected $primaryKey

Eloquent ORM 的默认主键是 id,如果你的主键并非 id 你可以通过 $primaryKey 属性来自定义你的主键。

 protected $primaryKey = 'post_id'; // 此处填写你的实际数据表主键

提示: 关于更多自定属性我们将在稍后陆续说明。

下面我们可以通过以下命令来执行迁移(migration),迁移是 Eloquent ORM 用来创建数据表的命令,以后你就可以通过代码创建数据表,这样做的好处是方便多人本地开发而造成的数据库同步问题。

$ php artisan migrate

在我们程序 database/migrations 中,我们可以找到名为 xxxx_xx_xx_xxxxxx_create_user_table.php 的文件,我们可以看到该文件中是一个继承了 Illuminate\Database\Migrations\Migration 名为 CreateUserTable 的类,该类中你可以在 up 方法中看到我们数据表中的列, Eloquent ORM 就是根据他来创建你的表的。

save() 方法

Laravel 框架提供了一系列快捷命令可以使用,然后运行以下命令:

$ php artisan tinker

然后我们就可以通过命令行交互的形式创建用户了。

>>> $user = new \App\User;
>>> $user->name = “Samfield Hawb”;
>>> $user->email = “samfield4sure@gmail.com”;
>>> $user->password = bcrypt(“secret”);
>>> $user->save(); //eloquent save() method
>>> exit
$ Exit:  Goodbye

Eloquent ORM 的 save() 方法帮助我们将这里的的 User 实例($user)转化为相应操作的 Sql 语句,这样我们就不用再担心 Sql 问题了。

create() 方法

同样的 Eloquent ORM 提供了create() 静态方法,接受一个数组作为参数,数组 key 对应数据表列名。

$user = \App\User::create([
    'name' => 'Samfield Hawb',
    'email' => 'samfield4sure@gmail.com',
    'password' => bcrypt('secret')//create an encrypted password
]);

create() 方法将返回一个 $user实例。

属性 Protected $fillable

该命令会在数据表中插入一条新的数据。当然前提是我们已经将我们需要填充的字段写到 $fillable 白名单,Eloquent ORM 是默认保护所有字段的,这样做是为了避免 批量注入 安全问题,所以当你遇到字段未按你的预期填充相应字段问题的时候,请先检查该字段下是否已经在 $fillable

根据Laravel 文档可以看到:

当 Http 请求中携带大量的非约定字段的时候就会发生 批量注入 安全问题, 这将会影响你一些你预期之外的字段。例如,你表字段中存在 is_admin,如果恶意用户通过 Http 请求传递了 is_admin 参数,在你未做好足够判定的时候,他将会被提升为管理员。

所以,默认将全部字段加入保护属性是很有必要的,不要嫌麻烦,这是为了安全考虑。

    /**
     *  字段白名单
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

属性 Protected $guarded

既然有白名单,那肯定会有相应的’黑名单’,属性 $guarded 就是为了这个产生的,guarded 意为守卫,添加在此属性中的字段将会受到保护。

    /**
     * 添加需要保护的字段
     *
     * @var array
     */
    protected $gaurded = [
        'password',
    ];

方法 all() method

我们可以通过 all() 方法来获取某个数据表中的全部数据,接上面的例子,现在获取我们的全部用户数据:

$users = App\User::all(); 

通过 all() 方法,Eloquent ORM 通过生成相应的 Sql 语句,查询并返回 User 表中所有数据的 集合。下面是生成的 sql 预览,(这里以 mysql 为例)

SELECT * from users

通过返回的数据 集合 我们可以轻松地操作数据,下面我们打印全部用户姓名:

foreach ($users as $user)
{
    echo $user->name;
}
//Samfield Hawb

find()

Laravel Eloquent为我们提供了find()方法,一种可用于获取一个或多个模型记录实例的方法。当你向find方法传递一个主键时,它返回与主键匹配的一条记录,如果找不到该记录,Eloquent就返回一个null。

 $user = App\User::find(1);

在这里我们使用Eloquent查询一个id为1的用户模型

SELECT * FROM users WHERE id=1

find() 也可以接受数组

$users = App\User::find([1,2,3]); 

完成此操作后,Eloquent底层会获取并返回传递给它的主键的记录集合。

findOrFail() 方法

大多数情况下,我们可能想在按主键查询不到模型时抛出错误。这里可以在我们的模型上通过调用 findOrFail() 方法来达成目的

 $user = App\User::findOrFail(1);

当模型查询不到时,一个 Illuminate\Database\Eloquent\ModelNotFoundException 异常会被抛出。若不处理该异常,一个 404 超文本传输协议 响应会被自动返回给用户,这是 Laravel 处理 ModelNotFoundExeption 错误的方法。

结论

至此你已基本了解 eloquent 如何让查询变得简单。留意我的下一篇文章,我们将用行动继续了解 Eloquent ORM 超级力量的旅程。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://dev.to/teamxenox/mastering-larav...

译文地址:https://learnku.com/laravel/t/43928

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 1

Eleoment 使用是方便简单很多,相对于直接使用 where 查询效率有所降低,在不使用缓存的情况下还有没有提高执行的效率的空间呢?

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!