LoginSignup
95
99

More than 3 years have passed since last update.

Laravel よく使うクエリビルダと複雑なwhere

Last updated at Posted at 2020-02-08

DBファサードのテーブルメソッドを使ってクエリ文を作成してデータを取得する

DBファサードは select、update、insert、delete、statementのクエリタイプごとにメソッドが用意されている

https://readouble.com/laravel/5.5/ja/queries.html
データベースクエリビルダはスラスラと書ける(fluent)便利なインターフェイスで、クエリを作成し実行するために使用します。アプリケーションで行われるほとんどのデーターベース操作が可能で、サポートしている全データベースシステムに対し使用できます。

LaravelクエリビルダはアプリケーションをSQLインジェクション攻撃から守るために、PDOパラメーターによるバインディングを使用します。バインドする文字列をクリーンにしてから渡す必要はありません。

よく使うクエリビルダ

select() 基本的なクエリの実行

$item = DB::select('SELECT * FROM items');

DBからのデータ取得

基本 get()でテーブルのすべてのデータを取得

$items = DB::table('テーブル名')->get();

// Eloquent(Model)を作成するとDB::table()を使わなくて良くなる
// Itemモデルを作った場合
$items = App\Item::get();

// AppネームスペースでItemをuseで追加しておくとシンプルに書ける
use App\Item;
$items = item::get();

first() 最初のひとつだけ取得

// たくさん得られるデータから最初のひとつだけ取得
// (並べ替えしていない場合idの昇順$id=1)
$items = Item::first();

take() 個数を指定して取得

// 複数取得できる中から個数を選択して取得
$items = Item::take(3)->get();

find() idを指定して取得

$item = Item::find(2);

chunk() 指定の件数ごとに取得

// 2件ごとにデータを纏めて取得6件あった場合[2, 2, 2]のようなまとまりになる
$items = Item::chunk(2);

select() カラム指定で取得

// nameのみ取得する場合
$items = Item::select('name')->get();
// 複数指定する場合(idとnameを取得する場合)
$items = Item::select('id', 'name')->get();

value() 指定したかカラムの値を1つ取得

// where()で指定したレコードを取得する
// id=2,3の2つのレコードの場合where('id', [2, 3])
// valueでカラムを絞り込んで値を取得する
$items = Item::where('id', [2, 3])->value('name');
// この例ではid=2,3のnameカラムの値を1つ取得する
// このように配列でレコードを2つ指定しても値は1つしか取れない

pluck() 指定したカラムの値すべて取得

// 指定したカラム名のデータをすべて取得
$items = Item::pluck('name');
// 第二引数にkeyを指定してkey=>valueの形で2つ取得できる
$items = Item::pluck('name', 'id');
    // $id => $name

where(), orWhere 該当するデータだけ取得

// 'name'カラムが'名前1'のレコードを取得したい場合
$items = Item::where('name', '名前1')->first();

// A and B
// 'name'カラムが'名前1'でかつ'name'カラムが'名前2'のレコードを取得したい場合
$items = Item::where('name', '名前1')->where('name', '名前2')->first();

// A or B
// 'name'カラムが'名前1'のレコードもしくは'name'カラムが'名前2'のレコードを取得したい場合
$items = Item::where('name', '名前1')
        ->orWhere('name', '名前2')
        ->first();

// (A and B) or C (andが強いため特別な処理は必要ない)
// 'name'カラムが'名前1'かつ'name'カラムが'名前2'のレコードもしくは'name'カラムが'名前3'のレコードを取得したい場合
$items = Item::where('name', '名前1')
        ->where('name', '名前2')
        ->orWhere('name', '名前3')
        ->first();

// A or (B and C)
// 'name'カラムが'名前1'かつ'name'カラムが'名前2'のレコードもしくは'name'カラムが'名前3'のレコードを取得したい場合
$items = Item::where('name', '名前1')
        ->orWhere('name', '名前2')
        ->where('name', '名前3')
        ->first();

// A and (B or C)
// 'name'カラムが'名前1'のレコード、かつ'name'カラムが'名前2'もしくは'name'カラムが'名前3'のレコードを取得したい場合
$items = Item::where('name', '名前1')
        ->where(function($query) {
        $query->where('name', '名前2')
              ->orwhere('name', '名前3')
        })
        ->first();

// (A and B) or (C and D)
$items = Item::where('name', '名前1')
        ->where('name', '名前2')
        ->orWhere(function($query) {
        $query->where('name', '名前2')
              ->where('name', '名前3')
        })
        ->first();

// (A or B) and (C or D)
$items = Item::where(function($query) {
        $query->orWhere('name', '名前1')
              ->orWhere('name', '名前2')
        ->where(function($query) {
        $query->orWhere('name', '名前2')
              ->orWhere('name', '名前3')
        })
        ->first();

// 関数を使う場合で変数を使いたい場合はuseを使う
$items = Item::where('name', '名前1')
        ->where(function($query)use($user) {
        $query->where('name', '$user->name')
              ->orwhere('name', '$user->name')
          })
        ->first();

ログインユーザー情報の取得

$user = Auth::user();
// ログインにかかわらず登録ユーザー情報を取得する場合は
$user = User::get();

(補足)tinkerで認証をする場合

// そのままだと次のようになる
>>> Auth::user()
 => null
// 認証が済んでないのでidを指定してログインする
>>> auth()->loginUsingId(1);
// id確認も可能
>>> auth()->id()
 => 1
>>> Auth::user()
 => //

リレーション先のデータを取得

with() リレーション先と一緒に取得

// ItemがbelongsTo('App\Content');とする
$items = Item::with('contents')->get();


App\Order::join('users', 'orders.user_id', '=', 'users.id')->get()

取得したデータの保存

save() 既存データと異なれば保存

データが同じであれば保存されずupdated_atも更新されない

$item = Item::find(1)
$item->name = $request->name;
$item->save();

save前に更新されたか確認

isDirty()を使うことで変更されているかどうか確認ができる
変更されていればtrue、されていなければ(更新せずに更新ボタンが押された場合)falseを返す

$order = App\Order::find(1);
$order->price = 50000; // 変更前20000の場合
$order->isDirty() // 返り値true
$order->save();

update() 既存データを確認せず更新保存

データが同じであっても上書きされupdated_atも更新される

$item = Item::find(1)->update(['name' => $request->name]);
95
99
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
95
99