首页 » Web技术 » Laravel » 正文

[Laravel 5 教程学习笔记] 八、Eloquent ORM

Laravel提供了一个漂亮、简介的 Eloquent ORM管理数据库。每个数据表都可以有一个对应的模型。

基本用法

我们先从建立一个 Eloquent 模型开始。模型通常放在 app 目录下,但是您可以将它们放在任何地方,只要能通过 composer.json 自动载入。所有的 Eloquent 模型都继承于Illuminate\Database\Eloquent\Model

定义一个 Eloquent 模型

D:\wamp\www\laravel5>php artisan make:model Article

Model created successfully.
Created Migration: 2015_05_14_130235_create_articles_table

查看生成的 app/Article.php 文件:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Article extends Model {

	//

}

没有太多的代码,它继承了 Model 类中所有的方法。

注意:我们并没有告诉 Eloquent Article 模型会使用哪张表。若没有特别指定,系统会默认自动对应名称为「类名称的小写复数形态」的数据库表。因此上面的Article模型会自动对应前一节生成的 articles 表。也可以在类中通过 table 属性自定义对应的表。
protected $table = 'articles';

命令行工具 tinker 插入与读取数据

至此,我们已经生成了一个 Article 模型,现在来学习一个新的 Laravel 命令行工具:tinker

php artisan tinker

这里可以使用简单的PHP方法:

>>> $name = 'Specs';
=> "Specs"
>>> $name;
=> "Specs"
>>>

插入数据

>>> $article = new App\Article;
=> <App\Article #000000001eca044a000000000c5c582a> {}
>>> $article->title = 'My first article';
=> "My first article"
>>> $article->body = 'Lorem ipsum';
=> "Lorem ipsum"
>>> $article->published_at = Carbon\Carbon::now();
=> <Carbon\Carbon #000000001eca044f000000000c5ca26a> {
       date: "2015-05-14 13:26:16",
       timezone_type: 3,
       timezone: "UTC"
   }
>>> $article->toArray();
=> [
       "title"        => "My first article",
       "body"         => "Lorem ipsum",
       "published_at" => <Carbon\Carbon #000000001eca044f000000000c5ca26a> {
           date: "2015-05-14 13:26:16",
           timezone_type: 3,
           timezone: "UTC"
       }
   ]

#保存到数据库
>>> $article->save();
=> true
>>>

现在到数据库查看 articles 表,发现刚才的数据已经插入进去,是不是非常简单?也可以使用 tinker 命令直接查看:

>>> App\Article::all()->toArray();
=> [
       [
           "id"           => 1,
           "title"        => "My first article",
           "body"         => "Lorem ipsum",
           "created_at"   => "2015-05-14 13:26:28",
           "updated_at"   => "2015-05-14 13:26:28",
           "published_at" => "2015-05-14 13:26:16",
           "excerpt"      => null
       ]
   ]

更新数据

>>> $article->title = 'My updated First Article';
=> "My updated First Article"
>>> $article->save();
=> true
>>> App\Article::all()->toArray();
=> [
       [
           "id"           => 1,
           "title"        => "My updated First Article",
           "body"         => "Lorem ipsum",
           "created_at"   => "2015-05-14 13:26:28",
           "updated_at"   => "2015-05-14 13:31:46",
           "published_at" => "2015-05-14 13:26:16",
           "excerpt"      => null
       ]
   ]

此时数据已经被更新了。

数据查询

如何实现 select * from articles where id = 1; 这样的查询?

>>> $article = App\Article::find(1);
=> <App\Article #000000004a07a3890000000067179bdf> {
       id: 1,
       title: "My updated First Article",
       body: "Lorem ipsum",
       created_at: "2015-05-14 13:26:28",
       updated_at: "2015-05-14 13:31:46",
       published_at: "2015-05-14 13:26:16",
       excerpt: null
   }
>>> $article->toArray();
=> [
       "id"           => 1,
       "title"        => "My updated First Article",
       "body"         => "Lorem ipsum",
       "created_at"   => "2015-05-14 13:26:28",
       "updated_at"   => "2015-05-14 13:31:46",
       "published_at" => "2015-05-14 13:26:16",
       "excerpt"      => null
   ]
>>> $article->title;
=> "My updated First Article"
>>> $article->body;

如何实现 select * from articles where body = 'Lorem ipsum'; 这样的查询?

>>> $article = App\Article::where('body', 'Lorem ipsum')->get();
=> <Illuminate\Database\Eloquent\Collection #000000004a07a3730000000067179bdf> [

       <App\Article #000000004a07a3770000000067179bdf> {
           id: 1,
           title: "My updated First Article",
           body: "Lorem ipsum",
           created_at: "2015-05-14 13:26:28",
           updated_at: "2015-05-14 13:31:46",
           published_at: "2015-05-14 13:26:16",
           excerpt: null
       }
   ]
>>> $article = App\Article::where('body', 'Lorem ipsum')->first();
=> <App\Article #000000004a07a38b0000000067179bdf> {
       id: 1,
       title: "My updated First Article",
       body: "Lorem ipsum",
       created_at: "2015-05-14 13:26:28",
       updated_at: "2015-05-14 13:31:46",
       published_at: "2015-05-14 13:26:16",
       excerpt: null
   }

注意:第一种方式返回的是一个集合(Eloquent Collection),第二种返回的是一个普通的Article类。

批量赋值

当然我们可以通过上面的步骤一个字段一个字段的指定,然后插入数据库。但是现在我们想一次完成这些操作:

>>> $article = App\Article::create(['title' => 'New Article', 'body' => 'New Body', 'published_at' => Carbon\Carbon::now()]);
Illuminate\Database\Eloquent\MassAssignmentException with message 'title'

发现抛出了一个MassAssignmentException异常,这是Laravel的一个保护机制。比如,在一些特殊情况下我们需要直接利用表单的信息填充数据库记录,但是如果我们并没有在表单中添加密码字段,而黑客产生了密码字段连同我们的其他字段一起送回服务器,这可能会把我们的一些记录改为他们的,或者把他们的帐号从普通用户变成管理员。所以如果想像上面那样直接填充数据,我们必须明确的告诉Laravel我们的模型中哪些字段是可以直接填充的。

修改 App/Article.php 模型文件:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Article extends Model {

    protected $fillable = [
        'title',
        'body',
        'published_at'
    ];

}

现在,除了上面指定的三个字段,用户输入的所有其他字段都会被忽略,这样就确保了我们的应用更加安全。

退出 tinker 并重新打开(修改文件后重启 tinker 才会生效),重新运行刚才个命令:

>>> $article = App\Article::create(['title' => 'New Title', 'body' => 'New body'
, 'published_at' => Carbon\Carbon::now()]);
=> <App\Article #0000000059d1c4430000000041be01e5> {
       title: "New Title",
       body: "New body",
       published_at: <Carbon\Carbon #0000000059d1c4420000000041befba5> {
           date: "2015-05-14 14:00:52",
           timezone_type: 3,
           timezone: "UTC"
       },
       updated_at: "2015-05-14 14:00:52",
       created_at: "2015-05-14 14:00:52",
       id: 2
   }

执行成功了!并且,create() 方法会自动把数据插入数据库,而不用执行 save() 方法了。现在查看数据库,已经有两条数据了:

>>> App\Article::all()->toArray();
=> [
       [
           "id"           => 1,
           "title"        => "My updated First Article",
           "body"         => "Lorem ipsum",
           "created_at"   => "2015-05-14 13:26:28",
           "updated_at"   => "2015-05-14 13:31:46",
           "published_at" => "2015-05-14 13:26:16",
           "excerpt"      => null
       ],
       [
           "id"           => 2,
           "title"        => "New Title",
           "body"         => "New body",
           "created_at"   => "2015-05-14 14:00:52",
           "updated_at"   => "2015-05-14 14:00:52",
           "published_at" => "2015-05-14 14:00:52",
           "excerpt"      => null
       ]
   ]

 使用 tinker 更新数据的两种方法

方法一:就像前面那样,查询出数据,然后修改字段,之后用 save() 方法保存

>>> $article = App\Article::find(2);
=> <App\Article #0000000059d1c45f0000000041be01e5> {
       id: 2,
       title: "New Title",
       body: "New body",
       created_at: "2015-05-14 14:00:52",
       updated_at: "2015-05-14 14:00:52",
       published_at: "2015-05-14 14:00:52",
       excerpt: null
   }
>>> $article->body = 'Updated';
=> "Updated"
>>> $article->save();
=> true
>>> $article->toArray();
=> [
       "id"           => 2,
       "title"        => "New Title",
       "body"         => "Updated",
       "created_at"   => "2015-05-14 14:00:52",
       "updated_at"   => "2015-05-14 14:07:09",
       "published_at" => "2015-05-14 14:00:52",
       "excerpt"      => null
   ]

方法二:通过 update() 方法直接更新数据库

>>> $article = App\Article::find(2);
=> <App\Article #0000000059d1c4480000000041be01e5> {
       id: 2,
       title: "New Title",
       body: "Updated",
       created_at: "2015-05-14 14:00:52",
       updated_at: "2015-05-14 14:07:09",
       published_at: "2015-05-14 14:00:52",
       excerpt: null
   }
>>> $article->update(['body' => 'Updated Again']);
=> true
>>> $article->toArray();
=> [
       "id"           => 2,
       "title"        => "New Title",
       "body"         => "Updated Again",
       "created_at"   => "2015-05-14 14:00:52",
       "updated_at"   => "2015-05-14 14:08:39",
       "published_at" => "2015-05-14 14:00:52",
       "excerpt"      => null
   ]

本节完!


该篇属于专题:《Laravel 5 基础视频教程学习笔记

发表评论