LoginSignup
3
3

More than 5 years have passed since last update.

LaravelのEloquentORMを調べてみた

Last updated at Posted at 2016-11-30

基本は公式ドキュメントを参照

上からコピペしていけば、実行できるように書きました。手を動かすこと推奨です。

テーブル作成


drop table blogs;
drop table blog_comments;

CREATE TABLE `blogs` (
    `id` INT(10) UNSIGNED NOT NULL,
    `name` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
    `zip_code` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
    PRIMARY KEY (`id`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

CREATE TABLE `blog_comments` (
    `blog_id` INT(10) UNSIGNED NOT NULL,
    `comment` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
    `zip_code` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci'
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

zip_code?と、思った方。スネークケースがほしかったのです。。。

Eloquent ORMを継承したクラスのひな形作成


php artisan make:model Blog
php artisan make:model BlogComment

出来上がったクラスに多少手を加えたバージョン


<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    protected $table = 'blogs';
    protected $primaryKey = 'id';
    public $timestamps = false;

    public function comments()
    {
        return $this->hasMany('App\BlogComment');
    }
}

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class BlogComment extends Model
{
    protected $table = 'blog_comments';
    protected $primaryKey = 'blog_id';
    public $timestamps = false;

    public function blog()
    {
        return $this->belongsTo('App\Blog');
    }    
}

LaravelのREPLを使って、データ流し込み


php artisan tinker

DB::table('blogs')->delete();
DB::table('blog_comments')->delete();

DB::table('blogs')->insert(['id' => 1, 'name' => 'name1', 'zip_code' => '111-0001']);
DB::table('blogs')->insert(['id' => 2, 'name' => 'name2', 'zip_code' => '121-0001']);
DB::table('blog_comments')->insert(['blog_id' => 1, 'comment' => 'comment11', 'zip_code' => '111-0011']);
DB::table('blog_comments')->insert(['blog_id' => 1, 'comment' => 'comment12', 'zip_code' => '111-0012']);
DB::table('blog_comments')->insert(['blog_id' => 1, 'comment' => 'comment13', 'zip_code' => '111-0013']);
DB::table('blog_comments')->insert(['blog_id' => 2, 'comment' => 'comment21', 'zip_code' => '121-0021']);
DB::table('blog_comments')->insert(['blog_id' => 2, 'comment' => 'comment22', 'zip_code' => '121-0022']);
DB::table('blog_comments')->insert(['blog_id' => 2, 'comment' => 'comment23', 'zip_code' => '121-0023']);

ここまでで、下準備おわり。

実際に使ってみる


php artisan tinker

// blogsテーブルデータ全取得
$blogs = App\Blog::all();

// blog_commentsテーブルデータ全取得
$blogComments = App\BlogComment::all();

// Blogの子テーブル情報取得(hasMany)
$comments = App\Blog::find(1)->comments;

// Blogの情報に子テーブルの情報も付加して、さらにjsonにしたバージョン
$blogWithComment = App\Blog::with('comments')->find(1)->toJson();
=> {"id":1,"name":"name1","zip_code":"111-0001","comments":[{"blog_id":1,"comment":"comment11","zip_code":"111-0011"},{"bl
og_id":1,"comment":"comment12","zip_code":"111-0012"},{"blog_id":1,"comment":"comment13","zip_code":"111-0013"}]}

// BlogCommentの親テーブル情報取得(belongsTo)
$blogComment = App\BlogComment::find(1); // この時点で親の情報はSQLしてない。遅延ローディングらしい。
$blogComment->blog; // ここでSQLして、Blog情報を取ってきている。It's Magical Code.

// 3つ以上のブログコメントを持つblogの取得
$blog = App\Blog::has('comments', '>=', 3)->get();
=> Illuminate\Database\Eloquent\Collection {#703
     all: [
       App\Blog {#720
         id: 1,
         name: "name1",
         zip_code: "111-0001",
       },
     ],
   }

// mysqlのクエリログとか見ていないと、Eagerローディングの違いはわからないです。
// Eagerローディング無し(belongsTo)
$blogComments = App\BlogComment::all();
foreach ($blogComments  as $blogComment) {
    echo $blogComment->blog->name;
}

// Eagerローディング有り(belongsTo)
$blogComments = App\BlogComment::with('blog')->get();
foreach ($blogComments  as $blogComment) {
    echo $blogComment->blog->name;
}

まとめ


非効率なクエリとかあるかなぁ?と、クエリログ見ながら実行していたのですが、大丈夫そうでした。
ORMのコードを見ているとSQLがどうなるか?分からないものが多いですが、このORMは割とシンプルなほうかなぁと思いました。ただ、クラスの中身をしっかりと知らない状態では使えないので、学習コストはあるなぁという印象でした。

あ、mysqlのログ出す方法はwindowsでmysql5.7をzipインストールするを参照してみてください。(しょぼい設定だし、よく見るとwindowsって書いてありますが、iniファイルの部分だけなら変わらんですよ。たぶん。)

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3