【PHP(Laravel)】DBから値を抽出するSQL文の種類と違い

【PHP(Laravel)】DBから値を抽出するSQL文の種類と違い

検索流入があって記事が薄いものを補填していく流れの中の1つ。

今回は『Laravel×SQL文』についてです。

Laravelでは大別して2種類の書き方が出来る

  1. Eloquentで書く
  2. PHPのSQL文で書く

どちらもちゃんと動きます。
ただ、色々やってみた結果JOINがある場合はeloquentの方が圧倒的に速いです。

理由はModelsで書いたテーブルの関連性が事前準備されているからでしょう。
なので、LaravelではEloquentで記載する事がセオリーとなります。

クエリビルダを使わない場合(PHPのSQL文で書く)

// select
$results = \DB::select('select * from users where id = ?', [1[);
// insert
\DB::insert('insert into users (id, name) values (?, ?)', [1, 'hoge']);

違うと事は最初の呼出しでDBと動作をコールする事です。
DBのSelectを使うよと宣言してからPHP従来のselect文を記載します。
Joinなども従来通りで使います。

Eloquentと併用すると混乱してくるのは【テーブル名】のコールの仕方。
\DBを使った場合はテーブル名をそのまま記載しますが、Eloquentではモデル名を記載します。
その為、上の例ではテーブル名が複数形(Laravel命名規制により)になっています。

Eloquentの基本的な書き方

#where抽出の場合
$array = Model名::where('カラム名',値)->get();

#具体例
$array = saledata::where('salesdate',today())->get();

変数名を書いてモデル名と抽出条件を記載する。簡単ですよね。

EloquentでJoinはどうするのか

JoinはModelに記載します。

感覚としてはデータ連携の事前準備といった感じです。

PHPでのJoin文の場合、INNER JOIN(内部結合)/LEFT JOIN(外部結合)/RIGHT JOIN(外部結合)などありますが 、Modelにリレーションを記載した場合、基本的に外部結合になると考えていいと思います。

その為、リレーション先のテーブルで抽出した条件を持たせたいときはfunctionを利用して抽出します。

$array = saledata::where('salesdate',today())
  ->WhereHas('product',function($search) use($product_id){
    $search->where('id',product_id);
  })->get();

Modelでのリレーション事前準備

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Brand extends Model
{
    public function Product()
    {
        return $this->belongsTo('App\Models\Product');
    }
    
/* バリデータ */
    protected $guarded =array('id');

    public static $rules = array(
        'name' => 'required',
        'kana' => 'required'
    );
private $errors;
 
  public function validate($data)
  {
    $v = Validator::make($data, $this->rules);
 
    if ($v->fails())
    {
      // この部分注意
      $this->errors = $v->errors();
      return false;
    }
 
    return true;
  }
 
  public function errors()
  {
    return $this->errors;
  }
}

基本的な書き方はこんな感じです。
上の例の12行目【 return $this->belongsTo('App\Models\Product');】 belongsTo  の部分を変えていくことで様々なリレーションに対応できます。

『1対多』リレーション

親テーブル:hasMany
子テーブル:belongsTo

『1対1』リレーション

両テーブル共に:hasOne

『多対多』リレーション

中間テーブルが必要になります。詳しくは過去記事で。

Laravel:多対多リレーション作成時の注意点

Laravelで多対多リレーション作成時の注意点 Laravelを触りだして約1か月が経ちました。 その間に常時SSL化の為のServer移動があり急ぎの仕事を余儀なくされましたが、や…

事前準備が正しければJOINする必要はない

モデルでの指示が正しく、全て網羅していればEloquentでJOINしなくてもViewやControllerでリレーション先の値を取得する事が出来ます。

#salesdata と product がリレーションされているとして
#今日の販売履歴を取得する
$array = saledata::where('salesdate',today())->get();

#今日販売された商品のJANコードを取得する
foreach($array as $arr){
  $values[] = $arr->product->jan;
}

こんな感じで【->(アロー)】を使って取得したい情報を持つリレーションモデル名->カラム名を指示するだけです。

Modelで書いていないテーブルとJOINする

Modelで関連付けていないテーブルとJOINする事も出来ます。

$array = saledata::where('salesdate',today())
  ->join('products','products.id','=','saledatas.product_id')
  ->get();

まとめ

覚えてしまうまではSelectが無い事に違和感があって「どこがSQL文かわからない」なんて思ってましたが、慣れてしまうとEloquentは超楽です。

\ 最新情報をチェック /

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください