2016年10月5日 星期三

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

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

基本用法

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

定义一个 Eloquent 模型

  1. D:\wamp\www\laravel5>php artisan make:model Article
  2.  
  3. Model created successfully.
  4. Created Migration: 2015_05_14_130235_create_articles_table
查看生成的 app/Article.php 文件:
  1. php namespace App;
  2.  
  3. use Illuminate\Database\Eloquent\Model;
  4.  
  5. class Article extends Model {
  6.  
  7. //
  8.  
  9. }
没有太多的代码,它继承了 Model 类中所有的方法。
注意:我们并没有告诉 Eloquent Article 模型会使用哪张表。若没有特别指定,系统会默认自动对应名称为「类名称的小写复数形态」的数据库表。因此上面的Article模型会自动对应前一节生成的 articles 表。也可以在类中通过 table 属性自定义对应的表。
  1. protected $table = 'articles';

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

至此,我们已经生成了一个 Article 模型,现在来学习一个新的 Laravel 命令行工具:tinker
  1. php artisan tinker
这里可以使用简单的PHP方法:
  1. >>> $name = 'Specs';
  2. => "Specs"
  3. >>> $name;
  4. => "Specs"
  5. >>>

插入数据

  1. >>> $article = new App\Article;
  2. => <App\Article #000000001eca044a000000000c5c582a> {}
  3. >>> $article->title = 'My first article';
  4. => "My first article"
  5. >>> $article->body = 'Lorem ipsum';
  6. => "Lorem ipsum"
  7. >>> $article->published_at = Carbon\Carbon::now();
  8. => <Carbon\Carbon #000000001eca044f000000000c5ca26a> {
  9. date: "2015-05-14 13:26:16",
  10. timezone_type: 3,
  11. timezone: "UTC"
  12. }
  13. >>> $article->toArray();
  14. => [
  15. "title" => "My first article",
  16. "body" => "Lorem ipsum",
  17. "published_at" => <Carbon\Carbon #000000001eca044f000000000c5ca26a> {
  18. date: "2015-05-14 13:26:16",
  19. timezone_type: 3,
  20. timezone: "UTC"
  21. }
  22. ]
  23.  
  24. #保存到数据库
  25. >>> $article->save();
  26. => true
  27. >>>
现在到数据库查看 articles 表,发现刚才的数据已经插入进去,是不是非常简单?也可以使用tinker 命令直接查看:
  1. >>> App\Article::all()->toArray();
  2. => [
  3. [
  4. "id" => 1,
  5. "title" => "My first article",
  6. "body" => "Lorem ipsum",
  7. "created_at" => "2015-05-14 13:26:28",
  8. "updated_at" => "2015-05-14 13:26:28",
  9. "published_at" => "2015-05-14 13:26:16",
  10. "excerpt" => null
  11. ]
  12. ]

更新数据

  1. >>> $article->title = 'My updated First Article';
  2. => "My updated First Article"
  3. >>> $article->save();
  4. => true
  5. >>> App\Article::all()->toArray();
  6. => [
  7. [
  8. "id" => 1,
  9. "title" => "My updated First Article",
  10. "body" => "Lorem ipsum",
  11. "created_at" => "2015-05-14 13:26:28",
  12. "updated_at" => "2015-05-14 13:31:46",
  13. "published_at" => "2015-05-14 13:26:16",
  14. "excerpt" => null
  15. ]
  16. ]
此时数据已经被更新了。

数据查询

如何实现 select * from articles where id = 1; 这样的查询?
  1. >>> $article = App\Article::find(1);
  2. => <App\Article #000000004a07a3890000000067179bdf> {
  3. id: 1,
  4. title: "My updated First Article",
  5. body: "Lorem ipsum",
  6. created_at: "2015-05-14 13:26:28",
  7. updated_at: "2015-05-14 13:31:46",
  8. published_at: "2015-05-14 13:26:16",
  9. excerpt: null
  10. }
  11. >>> $article->toArray();
  12. => [
  13. "id" => 1,
  14. "title" => "My updated First Article",
  15. "body" => "Lorem ipsum",
  16. "created_at" => "2015-05-14 13:26:28",
  17. "updated_at" => "2015-05-14 13:31:46",
  18. "published_at" => "2015-05-14 13:26:16",
  19. "excerpt" => null
  20. ]
  21. >>> $article->title;
  22. => "My updated First Article"
  23. >>> $article->body;
如何实现 select * from articles where body = 'Lorem ipsum'; 这样的查询?
  1. >>> $article = App\Article::where('body', 'Lorem ipsum')->get();
  2. => <Illuminate\Database\Eloquent\Collection #000000004a07a3730000000067179bdf> [
  3.  
  4. <App\Article #000000004a07a3770000000067179bdf> {
  5. id: 1,
  6. title: "My updated First Article",
  7. body: "Lorem ipsum",
  8. created_at: "2015-05-14 13:26:28",
  9. updated_at: "2015-05-14 13:31:46",
  10. published_at: "2015-05-14 13:26:16",
  11. excerpt: null
  12. }
  13. ]
  14. >>> $article = App\Article::where('body', 'Lorem ipsum')->first();
  15. => <App\Article #000000004a07a38b0000000067179bdf> {
  16. id: 1,
  17. title: "My updated First Article",
  18. body: "Lorem ipsum",
  19. created_at: "2015-05-14 13:26:28",
  20. updated_at: "2015-05-14 13:31:46",
  21. published_at: "2015-05-14 13:26:16",
  22. excerpt: null
  23. }
注意:第一种方式返回的是一个集合(Eloquent Collection),第二种返回的是一个普通的Article类。

批量赋值

当然我们可以通过上面的步骤一个字段一个字段的指定,然后插入数据库。但是现在我们想一次完成这些操作:
  1. >>> $article = App\Article::create(['title' => 'New Article', 'body' => 'New Body', 'published_at' => Carbon\Carbon::now()]);
  2. Illuminate\Database\Eloquent\MassAssignmentException with message 'title'
发现抛出了一个MassAssignmentException异常,这是Laravel的一个保护机制。比如,在一些特殊情况下我们需要直接利用表单的信息填充数据库记录,但是如果我们并没有在表单中添加密码字段,而黑客产生了密码字段连同我们的其他字段一起送回服务器,这可能会把我们的一些记录改为他们的,或者把他们的帐号从普通用户变成管理员。所以如果想像上面那样直接填充数据,我们必须明确的告诉Laravel我们的模型中哪些字段是可以直接填充的。
修改 App/Article.php 模型文件:
  1. php namespace App;
  2.  
  3. use Illuminate\Database\Eloquent\Model;
  4.  
  5. class Article extends Model {
  6.  
  7. protected $fillable = [
  8. 'title',
  9. 'body',
  10. 'published_at'
  11. ];
  12.  
  13. }
现在,除了上面指定的三个字段,用户输入的所有其他字段都会被忽略,这样就确保了我们的应用更加安全。
退出 tinker 并重新打开(修改文件后重启 tinker 才会生效),重新运行刚才个命令:
  1. >>> $article = App\Article::create(['title' => 'New Title', 'body' => 'New body'
  2. , 'published_at' => Carbon\Carbon::now()]);
  3. => <App\Article #0000000059d1c4430000000041be01e5> {
  4. title: "New Title",
  5. body: "New body",
  6. published_at: <Carbon\Carbon #0000000059d1c4420000000041befba5> {
  7. date: "2015-05-14 14:00:52",
  8. timezone_type: 3,
  9. timezone: "UTC"
  10. },
  11. updated_at: "2015-05-14 14:00:52",
  12. created_at: "2015-05-14 14:00:52",
  13. id: 2
  14. }
执行成功了!并且,create() 方法会自动把数据插入数据库,而不用执行 save() 方法了。现在查看数据库,已经有两条数据了:
  1. >>> App\Article::all()->toArray();
  2. => [
  3. [
  4. "id" => 1,
  5. "title" => "My updated First Article",
  6. "body" => "Lorem ipsum",
  7. "created_at" => "2015-05-14 13:26:28",
  8. "updated_at" => "2015-05-14 13:31:46",
  9. "published_at" => "2015-05-14 13:26:16",
  10. "excerpt" => null
  11. ],
  12. [
  13. "id" => 2,
  14. "title" => "New Title",
  15. "body" => "New body",
  16. "created_at" => "2015-05-14 14:00:52",
  17. "updated_at" => "2015-05-14 14:00:52",
  18. "published_at" => "2015-05-14 14:00:52",
  19. "excerpt" => null
  20. ]
  21. ]

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

方法一:就像前面那样,查询出数据,然后修改字段,之后用 save() 方法保存
  1. >>> $article = App\Article::find(2);
  2. => <App\Article #0000000059d1c45f0000000041be01e5> {
  3. id: 2,
  4. title: "New Title",
  5. body: "New body",
  6. created_at: "2015-05-14 14:00:52",
  7. updated_at: "2015-05-14 14:00:52",
  8. published_at: "2015-05-14 14:00:52",
  9. excerpt: null
  10. }
  11. >>> $article->body = 'Updated';
  12. => "Updated"
  13. >>> $article->save();
  14. => true
  15. >>> $article->toArray();
  16. => [
  17. "id" => 2,
  18. "title" => "New Title",
  19. "body" => "Updated",
  20. "created_at" => "2015-05-14 14:00:52",
  21. "updated_at" => "2015-05-14 14:07:09",
  22. "published_at" => "2015-05-14 14:00:52",
  23. "excerpt" => null
  24. ]
方法二:通过 update() 方法直接更新数据库
  1. >>> $article = App\Article::find(2);
  2. => <App\Article #0000000059d1c4480000000041be01e5> {
  3. id: 2,
  4. title: "New Title",
  5. body: "Updated",
  6. created_at: "2015-05-14 14:00:52",
  7. updated_at: "2015-05-14 14:07:09",
  8. published_at: "2015-05-14 14:00:52",
  9. excerpt: null
  10. }
  11. >>> $article->update(['body' => 'Updated Again']);
  12. => true
  13. >>> $article->toArray();
  14. => [
  15. "id" => 2,
  16. "title" => "New Title",
  17. "body" => "Updated Again",
  18. "created_at" => "2015-05-14 14:00:52",
  19. "updated_at" => "2015-05-14 14:08:39",
  20. "published_at" => "2015-05-14 14:00:52",
  21. "excerpt" => null
  22. ]
本节完!


from : http://9iphp.com/web/laravel/laravel-5-eloquent-orm.html

沒有留言:

wibiya widget