نسخه:

پایگاه داده: Query Builder

معرفی

سازنده پرس و جو پایگاه داده لاراول یک رابط راحت و روان برای ایجاد و اجرای پرس و جوهای پایگاه داده ارائه می دهد. می توان از آن برای انجام اکثر عملیات پایگاه داده در برنامه کاربردی خود استفاده کرد و با تمام سیستم های پایگاه داده پشتیبانی شده لاراول کاملاً کار می کند.

سازنده پرس و جو لاراول از اتصال پارامتر PDO برای محافظت از برنامه شما در برابر حملات تزریق SQL استفاده می کند. نیازی به تمیز کردن یا پاکسازی رشته‌های ارسال شده به سازنده پرس و جو به عنوان پیوندهای پرس و جو وجود ندارد.

PDO از نام ستون های الزام آور پشتیبانی نمی کند. بنابراین، هرگز نباید به ورودی کاربر اجازه دهید نام ستون‌های ارجاع‌شده توسط درخواست‌های شما، از جمله ستون‌های «ترتیب براساس» را دیکته کند.

اجرای کوئری های پایگاه داده

بازیابی همه سطرها از یک جدول

می توانید از table روش ارائه شده توسط DB نما برای شروع یک پرس و جو استفاده کنید. این table متد یک نمونه سازنده پرس و جو روان را برای جدول داده شده برمی گرداند و به شما امکان می دهد محدودیت های بیشتری را به پرس و جو زنجیره ای بزنید و در نهایت نتایج پرس و جو را با استفاده از روش بازیابی کنید get :

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;
 
class UserController extends Controller
{
/**
* Show a list of all of the application's users.
*/
public function index(): View
{
$users = DB::table('users')->get();
 
return view('user.index', ['users' => $users]);
}
}

متد get یک Illuminate\Support\Collection نمونه حاوی نتایج پرس و جو را برمی گرداند که در آن هر نتیجه نمونه ای از stdClass شی PHP است. شما می توانید با دسترسی به ستون به عنوان ویژگی شی به مقدار هر ستون دسترسی پیدا کنید:

use Illuminate\Support\Facades\DB;
 
$users = DB::table('users')->get();
 
foreach ($users as $user) {
echo $user->name;
}

مجموعه های لاراول انواع مختلفی از روش های بسیار قدرتمند را برای نقشه برداری و کاهش داده ها ارائه می دهند. برای اطلاعات بیشتر در مورد مجموعه های لاراول، مستندات مجموعه را بررسی کنید .

بازیابی یک ردیف / ستون از یک جدول

اگر فقط نیاز به بازیابی یک ردیف از جدول پایگاه داده دارید، می توانید از روش DB نما استفاده کنید first . این متد یک شی واحد را برمی گرداند stdClass :

$user = DB::table('users')->where('name', 'John')->first();
 
return $user->email;

اگر به یک ردیف کامل نیاز ندارید، می‌توانید با استفاده از value روش، یک مقدار را از یک رکورد استخراج کنید. این روش مقدار ستون را مستقیماً برمی گرداند:

$email = DB::table('users')->where('name', 'John')->value('email');

برای بازیابی یک سطر با id مقدار ستون آن، از find روش زیر استفاده کنید:

$user = DB::table('users')->find(3);

بازیابی لیستی از مقادیر ستون

اگر می خواهید Illuminate\Support\Collection نمونه ای حاوی مقادیر یک ستون واحد را بازیابی کنید، می توانید از pluck روش استفاده کنید. در این مثال، مجموعه ای از عناوین کاربران را بازیابی می کنیم:

use Illuminate\Support\Facades\DB;
 
$titles = DB::table('users')->pluck('title');
 
foreach ($titles as $title) {
echo $title;
}

می‌توانید با ارائه آرگومان دوم به متد، ستونی را که مجموعه حاصل باید از آن به عنوان کلید استفاده کند، مشخص کنید pluck :

$titles = DB::table('users')->pluck('title', 'name');
 
foreach ($titles as $name => $title) {
echo $title;
}

نتایج تکه تکه شدن

اگر نیاز به کار با هزاران رکورد پایگاه داده دارید، از chunk روش ارائه شده توسط DB نما استفاده کنید. این روش یک تکه کوچک از نتایج را در یک زمان بازیابی می کند و هر تکه را برای پردازش در یک بسته تغذیه می کند. به عنوان مثال، بیایید کل users جدول را در تکه های 100 رکورد در یک زمان بازیابی کنیم:

use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
 
DB::table('users')->orderBy('id')->chunk(100, function (Collection $users) {
foreach ($users as $user) {
// ...
}
});

false می‌توانید با بازگشت از بسته شدن ، پردازش تکه‌های بیشتر را متوقف کنید :

DB::table('users')->orderBy('id')->chunk(100, function (Collection $users) {
// Process the records...
 
return false;
});

اگر در حال به روز رسانی سوابق پایگاه داده در حین تجزیه نتایج هستید، نتایج تکه شما ممکن است به روش های غیرمنتظره ای تغییر کند. اگر قصد دارید رکوردهای بازیابی شده را در حین تکه تکه شدن به روز کنید، همیشه بهتر است به chunkById جای آن از روش استفاده کنید. این روش به طور خودکار نتایج را بر اساس کلید اصلی رکورد صفحه بندی می کند:

DB::table('users')->where('active', false)
->chunkById(100, function (Collection $users) {
foreach ($users as $user) {
DB::table('users')
->where('id', $user->id)
->update(['active' => true]);
}
});

هنگام به‌روزرسانی یا حذف سوابق درون پاسخ به تماس قطعه، هرگونه تغییر در کلید اصلی یا کلیدهای خارجی می‌تواند بر جستار قطعه تأثیر بگذارد. این به طور بالقوه می تواند منجر به عدم گنجاندن رکوردها در نتایج تکه تکه شود.

نتایج جریان با تنبلی

این متد lazy مشابه متد عمل می کند به chunk این معنا که پرس و جو را به صورت تکه ای اجرا می کند. با این حال، به جای ارسال هر تکه به یک فراخوان، lazy() متد یک را برمی گرداند LazyCollection که به شما امکان می دهد با نتایج به عنوان یک جریان واحد تعامل داشته باشید:

use Illuminate\Support\Facades\DB;
 
DB::table('users')->orderBy('id')->lazy()->each(function (object $user) {
// ...
});

یک بار دیگر، اگر قصد دارید رکوردهای بازیابی شده را در حین تکرار روی آنها به روز کنید، بهتر است به جای آن از روش های lazyById یا استفاده کنید lazyByIdDesc . این روش ها به طور خودکار نتایج را بر اساس کلید اصلی رکورد صفحه بندی می کنند:

DB::table('users')->where('active', false)
->lazyById()->each(function (object $user) {
DB::table('users')
->where('id', $user->id)
->update(['active' => true]);
});

هنگام به‌روزرسانی یا حذف رکوردها در حین تکرار روی آن‌ها، هرگونه تغییر در کلید اصلی یا کلیدهای خارجی می‌تواند بر جست‌وجوی قطعه تأثیر بگذارد. این به طور بالقوه می تواند منجر به عدم گنجاندن رکوردها در نتایج شود.

مصالح

سازنده پرس و جو همچنین روش های مختلفی را برای بازیابی مقادیر انبوه مانند count ،،،، و . پس از ساخت پرس و جو می توانید هر یک از این روش ها را فراخوانی کنید: max min avg sum

use Illuminate\Support\Facades\DB;
 
$users = DB::table('users')->count();
 
$price = DB::table('orders')->max('price');

البته، می‌توانید این روش‌ها را با بندهای دیگر ترکیب کنید تا نحوه محاسبه مقدار مجموع خود را دقیق کنید:

$price = DB::table('orders')
->where('finalized', 1)
->avg('price');

تعیین اینکه آیا رکوردها وجود دارند یا خیر

به جای استفاده از count روش برای تعیین اینکه آیا رکوردهایی وجود دارد که با محدودیت های پرس و جو شما مطابقت دارد یا خیر، می توانید از روش exists و استفاده کنید: doesntExist

if (DB::table('orders')->where('finalized', 1)->exists()) {
// ...
}
 
if (DB::table('orders')->where('finalized', 1)->doesntExist()) {
// ...
}

بیانیه ها را انتخاب کنید

تعیین یک بند انتخاب

ممکن است همیشه نخواهید همه ستون ها را از جدول پایگاه داده انتخاب کنید. با استفاده از select متد، می توانید یک عبارت "انتخاب" سفارشی برای پرس و جو تعیین کنید:

use Illuminate\Support\Facades\DB;
 
$users = DB::table('users')
->select('name', 'email as user_email')
->get();

این distinct متد به شما اجازه می‌دهد تا پرس و جو را مجبور کنید تا نتایج متمایز را برگرداند:

$users = DB::table('users')->distinct()->get();

اگر قبلاً یک نمونه سازنده کوئری دارید و می‌خواهید یک ستون به عبارت انتخابی موجود آن اضافه کنید، می‌توانید از addSelect روش استفاده کنید:

$query = DB::table('users')->select('name');
 
$users = $query->addSelect('age')->get();

عبارات خام

گاهی اوقات ممکن است لازم باشد یک رشته دلخواه را در یک پرس و جو وارد کنید. برای ایجاد یک عبارت رشته خام، می توانید از raw روش ارائه شده توسط DB نما استفاده کنید:

$users = DB::table('users')
->select(DB::raw('count(*) as user_count, status'))
->where('status', '<>', 1)
->groupBy('status')
->get();

دستورات خام به صورت رشته ای به پرس و جو تزریق می شوند، بنابراین باید بسیار مراقب باشید تا از ایجاد آسیب پذیری های تزریق SQL خودداری کنید.

روش های خام

به جای استفاده از DB::raw متد، می‌توانید از روش‌های زیر نیز برای درج یک عبارت خام در بخش‌های مختلف درخواست خود استفاده کنید. به یاد داشته باشید، لاراول نمی تواند تضمین کند که هر درخواستی که از عبارات خام استفاده می کند در برابر آسیب پذیری های تزریق SQL محافظت می شود.

selectRaw

روش selectRaw را می توان به جای استفاده کرد addSelect(DB::raw(/* ... */)) . این متد یک آرایه اختیاری از اتصالات را به عنوان آرگومان دوم خود می پذیرد:

$orders = DB::table('orders')
->selectRaw('price * ? as price_with_tax', [1.0825])
->get();

whereRaw / orWhereRaw

از whereRaw و orWhereRaw متدها می توان برای تزریق یک عبارت خام «where» به درخواست شما استفاده کرد. این متدها یک آرایه اختیاری از اتصالات را به عنوان آرگومان دوم خود می پذیرند:

$orders = DB::table('orders')
->whereRaw('price > IF(state = "TX", ?, 100)', [200])
->get();

havingRaw / orHavingRaw

متدهای havingRaw و orHavingRaw ممکن است برای ارائه یک رشته خام به عنوان مقدار عبارت "داشتن" استفاده شوند. این متدها یک آرایه اختیاری از اتصالات را به عنوان آرگومان دوم خود می پذیرند:

$orders = DB::table('orders')
->select('department', DB::raw('SUM(price) as total_sales'))
->groupBy('department')
->havingRaw('SUM(price) > ?', [2500])
->get();

orderByRaw

این orderByRaw روش ممکن است برای ارائه یک رشته خام به عنوان مقدار عبارت "order by" استفاده شود:

$orders = DB::table('orders')
->orderByRaw('updated_at - created_at DESC')
->get();

groupByRaw

این groupByRaw روش ممکن است برای ارائه یک رشته خام به عنوان مقدار عبارت استفاده شود group by :

$orders = DB::table('orders')
->select('city', 'state')
->groupByRaw('city, state')
->get();

می پیوندد

بند پیوستن داخلی

همچنین ممکن است از سازنده پرس و جو برای افزودن بندهای پیوستن به جستارهای شما استفاده شود. برای انجام یک "اتصال داخلی" اساسی، می توانید از این join روش در یک نمونه سازنده کوئری استفاده کنید. اولین آرگومان ارسال شده به join متد، نام جدولی است که باید به آن بپیوندید، در حالی که آرگومان های باقی مانده، محدودیت های ستون را برای اتصال مشخص می کنند. حتی می توانید چندین جدول را در یک پرس و جو بپیوندید:

use Illuminate\Support\Facades\DB;
 
$users = DB::table('users')
->join('contacts', 'users.id', '=', 'contacts.user_id')
->join('orders', 'users.id', '=', 'orders.user_id')
->select('users.*', 'contacts.phone', 'orders.price')
->get();

بند پیوستن چپ / راست عضویت

اگر می‌خواهید به جای «پیوستن درونی» یک «پیوستن چپ» یا «پیوستن راست» انجام دهید، از روش‌های leftJoin یا استفاده کنید rightJoin . این متدها دارای امضای یکسانی با join متد هستند:

$users = DB::table('users')
->leftJoin('posts', 'users.id', '=', 'posts.user_id')
->get();
 
$users = DB::table('users')
->rightJoin('posts', 'users.id', '=', 'posts.user_id')
->get();

بند عضویت متقاطع

می‌توانید از این crossJoin روش برای انجام «پیوستن متقاطع» استفاده کنید. اتصالات متقاطع یک محصول دکارتی بین جدول اول و جدول متصل ایجاد می کند:

$sizes = DB::table('sizes')
->crossJoin('colors')
->get();

بندهای عضویت پیشرفته

همچنین می توانید بندهای پیوستن پیشرفته تری را مشخص کنید. برای شروع، یک closure را به عنوان آرگومان دوم به join متد ارسال کنید. بسته شدن Illuminate\Database\Query\JoinClause نمونه ای دریافت می کند که به شما امکان می دهد محدودیت هایی را در عبارت "join" مشخص کنید:

DB::table('users')
->join('contacts', function (JoinClause $join) {
$join->on('users.id', '=', 'contacts.user_id')->orOn(/* ... */);
})
->get();

اگر می‌خواهید از عبارت «where» در اتصال‌های خود استفاده کنید، می‌توانید از روش‌های where و orWhere ارائه‌شده توسط JoinClause نمونه استفاده کنید. به جای مقایسه دو ستون، این روش ها ستون را با یک مقدار مقایسه می کنند:

DB::table('users')
->join('contacts', function (JoinClause $join) {
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.user_id', '>', 5);
})
->get();

Subquery Joins

می توانید از روش های joinSub , leftJoinSub و rightJoinSub برای پیوستن یک پرس و جو به یک پرسش فرعی استفاده کنید. هر یک از این روش‌ها سه آرگومان دریافت می‌کنند: subquery، نام مستعار جدول آن، و یک بسته که ستون‌های مرتبط را تعریف می‌کند. در این مثال، مجموعه‌ای از کاربران را بازیابی می‌کنیم که در آن هر رکورد کاربر دارای created_at مهر زمانی آخرین پست وبلاگ کاربر است:

$latestPosts = DB::table('posts')
->select('user_id', DB::raw('MAX(created_at) as last_post_created_at'))
->where('is_published', true)
->groupBy('user_id');
 
$users = DB::table('users')
->joinSub($latestPosts, 'latest_posts', function (JoinClause $join) {
$join->on('users.id', '=', 'latest_posts.user_id');
})->get();

اتصالات جانبی

پیوستن های جانبی در حال حاضر توسط PostgreSQL، MySQL >= 8.0.14 و SQL Server پشتیبانی می شوند.

می‌توانید از روش‌های joinLateral و leftJoinLateral برای انجام «اتصال جانبی» با یک پرسش فرعی استفاده کنید. هر یک از این متدها دو آرگومان دریافت می‌کنند: subquery و نام مستعار جدول آن. شرط(های) پیوستن باید در where بند درخواست فرعی داده شده مشخص شود. پیوندهای جانبی برای هر ردیف ارزیابی می شوند و می توانند به ستون های خارج از پرس و جو ارجاع دهند.

در این مثال، مجموعه ای از کاربران و همچنین سه پست اخیر وبلاگ کاربر را بازیابی می کنیم. هر کاربر می تواند حداکثر سه ردیف در مجموعه نتایج ایجاد کند: یکی برای هر یک از آخرین پست های وبلاگ خود. شرط پیوستن با whereColumn عبارتی در پرس و جوی فرعی مشخص می شود که به ردیف کاربر فعلی ارجاع می دهد:

$latestPosts = DB::table('posts')
->select('id as post_id', 'title as post_title', 'created_at as post_created_at')
->whereColumn('user_id', 'users.id')
->orderBy('created_at', 'desc')
->limit(3);
 
$users = DB::table('users')
->joinLateral($latestPosts, 'latest_posts')
->get();

اتحادیه ها

سازنده پرس و جو همچنین یک روش مناسب برای "اتحاد" دو یا چند پرس و جو با هم ارائه می دهد. به عنوان مثال، می توانید یک پرس و جو اولیه ایجاد کنید و از union روش برای اتحاد آن با پرس و جوهای بیشتر استفاده کنید:

use Illuminate\Support\Facades\DB;
 
$first = DB::table('users')
->whereNull('first_name');
 
$users = DB::table('users')
->whereNull('last_name')
->union($first)
->get();

علاوه بر union متد، سازنده پرس و جو یک unionAll متد نیز ارائه می دهد. جستارهایی که با استفاده از unionAll روش ترکیب می شوند، نتایج تکراری آنها حذف نمی شود. متد unionAll امضای متد مشابهی دارد union .

عبارات اصلی Where

که در آن بندها

می توانید از روش سازنده پرس و جو where برای افزودن بندهای "where" به پرس و جو استفاده کنید. ابتدایی ترین فراخوانی متد where به سه آرگومان نیاز دارد. اولین آرگومان نام ستون است. آرگومان دوم یک عملگر است که می تواند هر یک از عملگرهای پشتیبانی شده پایگاه داده باشد. آرگومان سوم مقداری است که باید با مقدار ستون مقایسه کرد.

به عنوان مثال، پرس و جوی زیر کاربرانی را بازیابی می کند که مقدار ستون votes برابر 100 و مقدار age ستون بزرگتر از 35 :

$users = DB::table('users')
->where('votes', '=', 100)
->where('age', '>', 35)
->get();

برای راحتی، اگر می خواهید بررسی کنید که یک ستون = به یک مقدار داده شده است، می توانید مقدار را به عنوان آرگومان دوم به where متد ارسال کنید. لاراول فرض می کند که می خواهید از = عملگر استفاده کنید:

$users = DB::table('users')->where('votes', 100)->get();

همانطور که قبلا ذکر شد، می توانید از هر اپراتوری که توسط سیستم پایگاه داده شما پشتیبانی می شود استفاده کنید:

$users = DB::table('users')
->where('votes', '>=', 100)
->get();
 
$users = DB::table('users')
->where('votes', '<>', 100)
->get();
 
$users = DB::table('users')
->where('name', 'like', 'T%')
->get();

همچنین می توانید یک آرایه از شرایط را به where تابع منتقل کنید. هر عنصر آرایه باید یک آرایه حاوی سه آرگومان باشد که معمولاً به where متد ارسال می شود:

$users = DB::table('users')->where([
['status', '=', '1'],
['subscribed', '<>', '1'],
])->get();

PDO از نام ستون های الزام آور پشتیبانی نمی کند. بنابراین، هرگز نباید به ورودی کاربر اجازه دهید نام ستون‌های ارجاع‌شده توسط درخواست‌های شما، از جمله ستون‌های «ترتیب براساس» را دیکته کند.

یا کجا بند

هنگام زنجیر کردن فراخوانی ها به متد سازنده پرس و جو where ، بندهای "where" با استفاده از and عملگر به یکدیگر متصل می شوند. با این حال، می توانید از orWhere روش برای پیوستن یک عبارت به پرس و جو با استفاده از or عملگر استفاده کنید. متد orWhere همان آرگومان های where متد را می پذیرد:

$users = DB::table('users')
->where('votes', '>', 100)
->orWhere('name', 'John')
->get();

اگر نیاز دارید یک شرط "یا" را در داخل پرانتز گروه بندی کنید، می توانید یک بسته را به عنوان اولین آرگومان برای متد ارسال کنید orWhere :

$users = DB::table('users')
->where('votes', '>', 100)
->orWhere(function (Builder $query) {
$query->where('name', 'Abigail')
->where('votes', '>', 50);
})
->get();

مثال بالا SQL زیر را تولید می کند:

select * from users where votes > 100 or (name = 'Abigail' and votes > 50)

همیشه باید orWhere تماس‌ها را گروه‌بندی کنید تا از رفتار غیرمنتظره در هنگام اعمال دامنه‌های جهانی جلوگیری کنید.

جایی که بندها نیست

متدهای whereNot و orWhereNot ممکن است برای نفی گروه معینی از محدودیت‌های پرس و جو استفاده شوند. به عنوان مثال، درخواست زیر محصولاتی را که در ترخیص هستند یا قیمتی کمتر از ده دارند را حذف می کند:

$products = DB::table('products')
->whereNot(function (Builder $query) {
$query->where('clearance', true)
->orWhere('price', '<', 10);
})
->get();

کجا هر / همه بندها

گاهی اوقات ممکن است لازم باشد که محدودیت های پرس و جوی یکسانی را در چندین ستون اعمال کنید. به عنوان مثال، ممکن است بخواهید تمام رکوردهایی را که در آن ستون‌های یک لیست معین LIKE یک مقدار مشخص هستند، بازیابی کنید. شما می توانید این کار را با استفاده از whereAny روش زیر انجام دهید:

$users = DB::table('users')
->where('active', true)
->whereAny([
'name',
'email',
'phone',
], 'LIKE', 'Example%')
->get();

پرس و جوی بالا منجر به SQL زیر می شود:

SELECT *
FROM users
WHERE active = true AND (
name LIKE 'Example%' OR
email LIKE 'Example%' OR
phone LIKE 'Example%'
)

به طور مشابه، این whereAll روش ممکن است برای بازیابی رکوردهایی استفاده شود که در آن تمام ستون های داده شده با یک محدودیت مشخص مطابقت دارند:

$posts = DB::table('posts')
->where('published', true)
->whereAll([
'title',
'content',
], 'LIKE', '%Laravel%')
->get();

پرس و جوی بالا منجر به SQL زیر می شود:

SELECT *
FROM posts
WHERE published = true AND (
title LIKE '%Laravel%' AND
content LIKE '%Laravel%'
)

JSON Where Clauses

لاراول همچنین از انواع ستون‌های JSON در پایگاه‌های داده که از انواع ستون‌های JSON پشتیبانی می‌کنند، پشتیبانی می‌کند. در حال حاضر، این شامل MySQL 8.0+، PostgreSQL 12.0+، SQL Server 2017+ و SQLite 3.39.0+ (با پسوند JSON1 ) است. برای پرس و جو از یک ستون JSON، از -> عملگر استفاده کنید:

$users = DB::table('users')
->where('preferences->dining->meal', 'salad')
->get();

می توانید whereJsonContains برای پرس و جو از آرایه های JSON استفاده کنید:

$users = DB::table('users')
->whereJsonContains('options->languages', 'en')
->get();

اگر برنامه شما از پایگاه داده MySQL یا PostgreSQL استفاده می کند، می توانید یک آرایه از مقادیر را به whereJsonContains متد ارسال کنید:

$users = DB::table('users')
->whereJsonContains('options->languages', ['en', 'de'])
->get();

می توانید از whereJsonLength روشی برای پرس و جو از آرایه های JSON بر اساس طول آنها استفاده کنید:

$users = DB::table('users')
->whereJsonLength('options->languages', 0)
->get();
 
$users = DB::table('users')
->whereJsonLength('options->languages', '>', 1)
->get();

بند های اضافی Where

WhereBetween / یاWhereBetween

این whereBetween روش تأیید می کند که مقدار یک ستون بین دو مقدار است:

$users = DB::table('users')
->whereBetween('votes', [1, 100])
->get();

WhereNotBetween / یاWhereNotBetween

این whereNotBetween روش تأیید می کند که مقدار یک ستون خارج از دو مقدار است:

$users = DB::table('users')
->whereNotBetween('votes', [1, 100])
->get();

WhereBetweenColumns / WhereNotBetweenColumns / orWhereBetweenColumns / orWhereNotBetweenColumns

این whereBetweenColumns روش تأیید می کند که مقدار یک ستون بین دو مقدار دو ستون در یک ردیف جدول قرار دارد:

$patients = DB::table('patients')
->whereBetweenColumns('weight', ['minimum_allowed_weight', 'maximum_allowed_weight'])
->get();

این whereNotBetweenColumns روش تأیید می‌کند که مقدار یک ستون خارج از دو مقدار دو ستون در یک ردیف جدول قرار دارد:

$patients = DB::table('patients')
->whereNotBetweenColumns('weight', ['minimum_allowed_weight', 'maximum_allowed_weight'])
->get();

WhereIn / WhereNotIn / یاWhereIn / یاWhereNotIn

این whereIn روش تأیید می کند که مقدار یک ستون معین در آرایه داده شده وجود دارد:

$users = DB::table('users')
->whereIn('id', [1, 2, 3])
->get();

این whereNotIn روش تأیید می کند که مقدار ستون داده شده در آرایه داده شده وجود ندارد:

$users = DB::table('users')
->whereNotIn('id', [1, 2, 3])
->get();

همچنین می توانید یک شی پرس و جو را به عنوان whereIn آرگومان دوم متد ارائه کنید:

$activeUsers = DB::table('users')->select('id')->where('is_active', 1);
 
$users = DB::table('comments')
->whereIn('user_id', $activeUsers)
->get();

مثال بالا SQL زیر را تولید می کند:

select * from comments where user_id in (
select id
from users
where is_active = 1
)

اگر آرایه بزرگی از اتصالات اعداد صحیح را به درخواست خود اضافه می‌کنید، ممکن است از روش‌های whereIntegerInRaw یا whereIntegerNotInRaw برای کاهش مصرف حافظه شما استفاده شود.

whereNull / whereNotNull / یاWhereNull / یاWhereNotNull

این whereNull روش تأیید می کند که مقدار ستون داده شده عبارت است از NULL :

$users = DB::table('users')
->whereNull('updated_at')
->get();

این whereNotNull روش تأیید می کند که مقدار ستون این نیست NULL :

$users = DB::table('users')
->whereNotNull('updated_at')
->get();

WhereDate / WhereMonth / WhereDay / WhereYear / WhereTime

این whereDate روش ممکن است برای مقایسه مقدار یک ستون با یک تاریخ استفاده شود:

$users = DB::table('users')
->whereDate('created_at', '2016-12-31')
->get();

این whereMonth روش ممکن است برای مقایسه مقدار یک ستون با یک ماه خاص استفاده شود:

$users = DB::table('users')
->whereMonth('created_at', '12')
->get();

این whereDay روش ممکن است برای مقایسه مقدار یک ستون با یک روز خاص از ماه استفاده شود:

$users = DB::table('users')
->whereDay('created_at', '31')
->get();

این whereYear روش ممکن است برای مقایسه مقدار یک ستون با یک سال خاص استفاده شود:

$users = DB::table('users')
->whereYear('created_at', '2016')
->get();

این whereTime روش ممکن است برای مقایسه مقدار یک ستون با یک زمان خاص استفاده شود:

$users = DB::table('users')
->whereTime('created_at', '=', '11:20:45')
->get();

WhereColumn / یاWhereColumn

این whereColumn روش ممکن است برای تأیید مساوی بودن دو ستون استفاده شود:

$users = DB::table('users')
->whereColumn('first_name', 'last_name')
->get();

همچنین می توانید یک عملگر مقایسه را به whereColumn متد ارسال کنید:

$users = DB::table('users')
->whereColumn('updated_at', '>', 'created_at')
->get();

همچنین می توانید آرایه ای از مقایسه ستون ها را به whereColumn متد ارسال کنید. این شرایط با استفاده از اپراتور ملحق خواهند شد and :

$users = DB::table('users')
->whereColumn([
['first_name', '=', 'last_name'],
['updated_at', '>', 'created_at'],
])->get();

گروه بندی منطقی

گاهی اوقات ممکن است لازم باشد چندین عبارت "where" را در داخل پرانتز گروه بندی کنید تا به گروه بندی منطقی مورد نظر خود برسید. در واقع، orWhere برای جلوگیری از رفتار غیرمنتظره پرس و جو، عموماً باید همیشه فراخوانی های متد داخل پرانتز را گروه بندی کنید . برای انجام این کار، ممکن است یک بسته به روش ارسال کنید where :

$users = DB::table('users')
->where('name', '=', 'John')
->where(function (Builder $query) {
$query->where('votes', '>', 100)
->orWhere('title', '=', 'Admin');
})
->get();

همانطور که می بینید، ارسال یک بسته به where متد به سازنده query دستور می دهد تا یک گروه محدودیت را شروع کند. بسته شدن یک نمونه سازنده پرس و جو دریافت می کند که می توانید از آن برای تنظیم محدودیت هایی که باید در گروه پرانتز قرار گیرند استفاده کنید. مثال بالا SQL زیر را تولید می کند:

select * from users where name = 'John' and (votes > 100 or title = 'Admin')

همیشه باید orWhere تماس‌ها را گروه‌بندی کنید تا از رفتار غیرمنتظره در هنگام اعمال دامنه‌های جهانی جلوگیری کنید.

بندهای پیشرفته Where

مواردی که وجود دارد

این whereExists متد به شما امکان می‌دهد که عبارت‌های SQL "where exists" را بنویسید. این whereExists متد بسته‌ای را می‌پذیرد که نمونه‌ای از سازنده پرس و جو را دریافت می‌کند و به شما امکان می‌دهد کوئری را که باید در داخل عبارت «وجود» قرار گیرد، تعریف کنید:

$users = DB::table('users')
->whereExists(function (Builder $query) {
$query->select(DB::raw(1))
->from('orders')
->whereColumn('orders.user_id', 'users.id');
})
->get();

همچنین، می‌توانید whereExists به جای بستن، یک شی query به متد ارائه دهید:

$orders = DB::table('orders')
->select(DB::raw(1))
->whereColumn('orders.user_id', 'users.id');
 
$users = DB::table('users')
->whereExists($orders)
->get();

هر دو مثال بالا SQL زیر را تولید می کنند:

select * from users
where exists (
select 1
from orders
where orders.user_id = users.id
)

موارد فرعی کجا

گاهی اوقات ممکن است لازم باشد یک عبارت "where" بسازید که نتایج یک پرس و جو فرعی را با یک مقدار مشخص مقایسه می کند. شما می توانید این کار را با ارسال یک بسته و یک مقدار به where متد انجام دهید. به عنوان مثال، پرس و جوی زیر تمام کاربرانی را که اخیراً «عضویت» از یک نوع معین دارند، بازیابی می کند.

use App\Models\User;
use Illuminate\Database\Query\Builder;
 
$users = User::where(function (Builder $query) {
$query->select('type')
->from('membership')
->whereColumn('membership.user_id', 'users.id')
->orderByDesc('membership.start_date')
->limit(1);
}, 'Pro')->get();

یا ممکن است لازم باشد یک بند "where" بسازید که یک ستون را با نتایج یک جستجوی فرعی مقایسه می کند. شما می توانید این کار را با ارسال یک ستون، عملگر و بسته شدن به where متد انجام دهید. به عنوان مثال، پرس و جو زیر تمام سوابق درآمدی را که مقدار آن کمتر از متوسط ​​است بازیابی می کند.

use App\Models\Income;
use Illuminate\Database\Query\Builder;
 
$incomes = Income::where('amount', '<', function (Builder $query) {
$query->selectRaw('avg(i.amount)')->from('incomes as i');
})->get();

متن کامل در کجا بند

متن کامل که در آن بندها در حال حاضر توسط MySQL و PostgreSQL پشتیبانی می شوند.

متدهای whereFullText و orWhereFullText ممکن است برای افزودن عبارت‌های متن کامل "where" به یک پرس و جو برای ستون‌هایی که دارای فهرست متن کامل هستند استفاده شود . این روش ها توسط لاراول به SQL مناسب برای سیستم پایگاه داده زیربنایی تبدیل می شوند. به عنوان مثال، یک MATCH AGAINST بند برای برنامه هایی که از MySQL استفاده می کنند ایجاد می شود:

$users = DB::table('users')
->whereFullText('bio', 'web developer')
->get();

سفارش، گروه بندی، محدودیت و افست

مرتب سازی

روش orderBy

این orderBy روش به شما امکان می دهد نتایج پرس و جو را بر اساس یک ستون مشخص مرتب کنید. اولین آرگومان پذیرفته شده توسط orderBy متد باید ستونی باشد که می خواهید بر اساس آن مرتب سازی کنید، در حالی که آرگومان دوم جهت مرتب سازی را تعیین می کند و ممکن است یکی asc یا desc :

$users = DB::table('users')
->orderBy('name', 'desc')
->get();

برای مرتب سازی بر اساس چندین ستون، می توانید به سادگی orderBy هر چند بار که لازم است فراخوانی کنید:

$users = DB::table('users')
->orderBy('name', 'desc')
->orderBy('email', 'asc')
->get();

و روش latest ها oldest

و متدها به شما امکان latest می oldest دهند به راحتی نتایج را بر اساس تاریخ سفارش دهید. به طور پیش فرض، نتیجه توسط ستون جدول مرتب می شود created_at . یا می‌توانید نام ستونی را که می‌خواهید بر اساس آن مرتب کنید، ارسال کنید:

$user = DB::table('users')
->latest()
->first();

ترتیب تصادفی

این inRandomOrder روش ممکن است برای مرتب کردن نتایج پرس و جو به صورت تصادفی استفاده شود. به عنوان مثال، می توانید از این روش برای واکشی یک کاربر تصادفی استفاده کنید:

$randomUser = DB::table('users')
->inRandomOrder()
->first();

حذف سفارشات موجود

این reorder متد تمام بندهای "order by" را که قبلاً روی پرس و جو اعمال شده اند حذف می کند:

$query = DB::table('users')->orderBy('name');
 
$unorderedUsers = $query->reorder()->get();

هنگام فراخوانی reorder متد، می‌توانید یک ستون و جهت ارسال کنید تا تمام بندهای «ترتیب بر اساس» موجود را حذف کنید و یک ترتیب کاملاً جدید در پرس و جو اعمال کنید:

$query = DB::table('users')->orderBy('name');
 
$usersOrderedByEmail = $query->reorder('email', 'desc')->get();

گروه بندی

و روش groupBy ها having

همانطور که ممکن است انتظار داشته باشید، ممکن است از روش های groupBy و having برای گروه بندی نتایج پرس و جو استفاده شود. امضای having متد مشابه امضای متد است where :

$users = DB::table('users')
->groupBy('account_id')
->having('account_id', '>', 100)
->get();

havingBetween برای فیلتر کردن نتایج در یک محدوده مشخص می توانید از روش استفاده کنید :

$report = DB::table('orders')
->selectRaw('count(id) as number_of_orders, customer_id')
->groupBy('customer_id')
->havingBetween('number_of_orders', [5, 15])
->get();

می توانید چندین آرگومان را به groupBy متد ارسال کنید تا بر اساس چندین ستون گروه بندی شود:

$users = DB::table('users')
->groupBy('first_name', 'status')
->having('account_id', '>', 100)
->get();

having برای ساخت عبارات پیشرفته تر ، havingRaw روش را ببینید.

Limit و Offset

و روش skip ها take

می‌توانید از روش‌های skip و take برای محدود کردن تعداد نتایج برگردانده شده از پرس و جو یا رد کردن تعداد معینی از نتایج در پرس و جو استفاده کنید:

$users = DB::table('users')->skip(10)->take(5)->get();

از طرف دیگر، می توانید از روش های limit و استفاده کنید offset . این روش‌ها از نظر عملکردی به ترتیب معادل روش‌های take و هستند skip :

$users = DB::table('users')
->offset(10)
->limit(5)
->get();

عبارت های شرطی

گاهی اوقات ممکن است بخواهید بندهای پرس و جوی خاصی بر اساس شرایط دیگری برای یک پرس و جو اعمال شوند. به عنوان مثال، ممکن است فقط بخواهید یک where دستور را اعمال کنید که یک مقدار ورودی داده شده در درخواست HTTP ورودی وجود داشته باشد. شما می توانید این کار را با استفاده از when روش زیر انجام دهید:

$role = $request->string('role');
 
$users = DB::table('users')
->when($role, function (Builder $query, string $role) {
$query->where('role_id', $role);
})
->get();

این when روش تنها زمانی بسته شدن داده شده را اجرا می کند که اولین آرگومان باشد true . اگر آرگومان اول باشد false ، بسته شدن اجرا نخواهد شد. بنابراین، در مثال بالا، بسته شدن متد when تنها در صورتی فراخوانی می‌شود که role فیلد در درخواست ورودی وجود داشته باشد و به true .

ممکن است یک بسته دیگر به عنوان آرگومان سوم به when متد ارسال کنید. این بسته شدن تنها در صورتی اجرا می شود که آرگومان اول به عنوان false . برای نشان دادن نحوه استفاده از این ویژگی، از آن برای پیکربندی ترتیب پیش‌فرض یک پرس و جو استفاده می‌کنیم:

$sortByVotes = $request->boolean('sort_by_votes');
 
$users = DB::table('users')
->when($sortByVotes, function (Builder $query, bool $sortByVotes) {
$query->orderBy('votes');
}, function (Builder $query) {
$query->orderBy('name');
})
->get();

درج بیانیه ها

سازنده پرس و جو همچنین insert روشی را ارائه می دهد که ممکن است برای درج رکوردها در جدول پایگاه داده استفاده شود. متد insert آرایه ای از نام ها و مقادیر ستون ها را می پذیرد:

DB::table('users')->insert([
'email' => 'kayla@example.com',
'votes' => 0
]);

شما می توانید چندین رکورد را همزمان با ارسال آرایه ای از آرایه ها وارد کنید. هر آرایه نشان دهنده رکوردی است که باید در جدول درج شود:

DB::table('users')->insert([
['email' => 'picard@example.com', 'votes' => 0],
['email' => 'janeway@example.com', 'votes' => 0],
]);

این insertOrIgnore روش هنگام درج رکوردها در پایگاه داده، خطاها را نادیده می گیرد. هنگام استفاده از این روش، باید توجه داشته باشید که خطاهای رکورد تکراری نادیده گرفته می شوند و انواع دیگر خطاها نیز بسته به موتور پایگاه داده ممکن است نادیده گرفته شوند. به عنوان مثال، حالت سخت MySQL را دور insertOrIgnore می زند :

DB::table('users')->insertOrIgnore([
['id' => 1, 'email' => 'sisko@example.com'],
['id' => 2, 'email' => 'archer@example.com'],
]);

این insertUsing روش رکوردهای جدیدی را در جدول درج می کند در حالی که از یک پرس و جو فرعی برای تعیین داده هایی که باید درج شوند استفاده می کند:

DB::table('pruned_users')->insertUsing([
'id', 'name', 'email', 'email_verified_at'
], DB::table('users')->select(
'id', 'name', 'email', 'email_verified_at'
)->where('updated_at', '<=', now()->subMonth()));

افزایش خودکار شناسه ها

اگر جدول دارای شناسه افزایش خودکار است، از insertGetId روش برای درج یک رکورد و سپس بازیابی شناسه استفاده کنید:

$id = DB::table('users')->insertGetId(
['email' => 'john@example.com', 'votes' => 0]
);

هنگام استفاده از PostgreSQL، insertGetId متد انتظار دارد که ستون افزایش خودکار نامگذاری شود id . اگر می خواهید شناسه را از یک "توالی" دیگر بازیابی کنید، می توانید نام ستون را به عنوان پارامتر دوم به متد ارسال کنید insertGetId .

بالاها

این upsert روش رکوردهایی را وارد می کند که وجود ندارند و رکوردهایی را که از قبل وجود دارند با مقادیر جدیدی که ممکن است مشخص کنید به روز می کند. آرگومان اول متد شامل مقادیری است که باید درج یا به‌روزرسانی شوند، در حالی که آرگومان دوم ستون(هایی) را فهرست می‌کند که رکوردها را در جدول مرتبط شناسایی می‌کنند. آرگومان سوم و آخر متد، آرایه‌ای از ستون‌ها است که در صورت وجود رکورد منطبق در پایگاه داده، باید به روز شوند:

DB::table('flights')->upsert(
[
['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
],
['departure', 'destination'],
['price']
);

در مثال بالا، لاراول سعی می کند دو رکورد را وارد کند. اگر رکوردی از قبل با مقادیر مشابه departure و destination ستونی وجود داشته باشد، لاراول ستون آن رکورد را به روز می کند price .

همه پایگاه‌های داده به جز SQL Server نیاز دارند که ستون‌های آرگومان دوم متد upsert دارای یک فهرست «اولیه» یا «محصول» باشند. علاوه بر این، درایور پایگاه داده MySQL آرگومان دوم متد را نادیده می گیرد upsert و همیشه از شاخص های "اولیه" و "یک" جدول برای شناسایی رکوردهای موجود استفاده می کند.

به روز رسانی بیانیه ها

علاوه بر درج رکوردها در پایگاه داده، سازنده پرس و جو همچنین می تواند رکوردهای موجود را با استفاده از update روش به روز کند. این update روش، مانند insert متد، آرایه‌ای از جفت‌های ستون و مقادیر را می‌پذیرد که نشان‌دهنده ستون‌هایی است که باید به‌روزرسانی شوند. این update روش تعداد ردیف های تحت تأثیر را برمی گرداند. می توانید update پرس و جو را با استفاده از where بندها محدود کنید:

$affected = DB::table('users')
->where('id', 1)
->update(['votes' => 1]);

به روز رسانی یا درج کنید

گاهی اوقات ممکن است بخواهید یک رکورد موجود در پایگاه داده را به روز کنید یا در صورت عدم وجود رکورد منطبق، آن را ایجاد کنید. در این سناریو، updateOrInsert ممکن است از روش استفاده شود. این updateOrInsert روش دو آرگومان را می پذیرد: یک آرایه از شرایط برای یافتن رکورد، و یک آرایه از جفت ستون و مقدار که ستون هایی را که باید به روز شوند را نشان می دهد.

این updateOrInsert روش تلاش خواهد کرد تا با استفاده از جفت‌های ستون و مقدار آرگومان اول، یک رکورد پایگاه داده منطبق را پیدا کند. اگر رکورد وجود داشته باشد، با مقادیر آرگومان دوم به روز می شود. اگر رکورد پیدا نشد، یک رکورد جدید با ویژگی های ادغام شده هر دو آرگومان درج می شود:

DB::table('users')
->updateOrInsert(
['email' => 'john@example.com', 'name' => 'John'],
['votes' => '2']
);

به روز رسانی ستون های JSON

هنگام به روز رسانی یک ستون JSON، باید از -> syntax برای به روز رسانی کلید مناسب در شی JSON استفاده کنید. این عملیات در MySQL 5.7+ و PostgreSQL 9.5+ پشتیبانی می‌شود:

$affected = DB::table('users')
->where('id', 1)
->update(['options->enabled' => true]);

افزایش و کاهش

سازنده پرس و جو همچنین روش های مناسبی را برای افزایش یا کاهش مقدار یک ستون مشخص ارائه می دهد. هر دوی این روش ها حداقل یک آرگومان را می پذیرند: ستونی که باید اصلاح شود. ممکن است یک آرگومان دوم برای تعیین مقداری که ستون باید افزایش یا کاهش یابد ارائه شود:

DB::table('users')->increment('votes');
 
DB::table('users')->increment('votes', 5);
 
DB::table('users')->decrement('votes');
 
DB::table('users')->decrement('votes', 5);

در صورت نیاز، می‌توانید ستون‌های دیگری را نیز برای به‌روزرسانی در طول عملیات افزایش یا کاهش مشخص کنید:

DB::table('users')->increment('votes', 1, ['name' => 'John']);

علاوه بر این، می توانید چندین ستون را به طور همزمان با استفاده از روش های incrementEach و افزایش یا کاهش دهید decrementEach :

DB::table('users')->incrementEach([
'votes' => 5,
'balance' => 100,
]);

حذف بیانیه ها

روش سازنده پرس و جو delete ممکن است برای حذف رکوردها از جدول استفاده شود. این delete روش تعداد ردیف های تحت تأثیر را برمی گرداند. قبل از فراخوانی متد ، می‌توانید delete عبارات را با اضافه کردن عبارت‌های "where" محدود کنید delete :

$deleted = DB::table('users')->delete();
 
$deleted = DB::table('users')->where('votes', '>', 100)->delete();

اگر می‌خواهید کل جدول را کوتاه کنید، که تمام رکوردها را از جدول حذف می‌کند و شناسه افزایش خودکار را به صفر می‌رساند، می‌توانید از truncate روش زیر استفاده کنید:

DB::table('users')->truncate();

جداسازی جدول و PostgreSQL

هنگام کوتاه کردن یک پایگاه داده PostgreSQL، این CASCADE رفتار اعمال خواهد شد. این بدان معنی است که تمام رکوردهای مربوط به کلید خارجی در سایر جداول نیز حذف خواهند شد.

قفل بدبینانه

سازنده پرس و جو همچنین شامل چند عملکرد است که به شما کمک می کند هنگام اجرای select عبارات خود به "قفل بدبینانه" برسید. برای اجرای یک دستور با "قفل مشترک"، می توانید sharedLock متد را فراخوانی کنید. یک قفل مشترک از اصلاح ردیف های انتخابی تا زمانی که تراکنش شما متعهد شود جلوگیری می کند:

DB::table('users')
->where('votes', '>', 100)
->sharedLock()
->get();

در غیر این صورت، می توانید از lockForUpdate روش استفاده کنید. قفل "برای به روز رسانی" از تغییر یا انتخاب سوابق انتخابی با یک قفل مشترک دیگر جلوگیری می کند:

DB::table('users')
->where('votes', '>', 100)
->lockForUpdate()
->get();

اشکال زدایی

می‌توانید هنگام ساخت پرس‌وجو از روش‌های dd و برای حذف پیوندهای پرس و جو فعلی و SQL استفاده کنید. dump این dd روش اطلاعات اشکال زدایی را نمایش می دهد و سپس اجرای درخواست را متوقف می کند. این dump روش اطلاعات اشکال زدایی را نمایش می دهد اما به درخواست اجازه می دهد تا اجرا ادامه یابد:

DB::table('users')->where('votes', '>', 100)->dd();
 
DB::table('users')->where('votes', '>', 100)->dump();

متدهای dumpRawSql و ddRawSql ممکن است در یک پرس و جو فراخوانی شوند تا SQL پرس و جو را با تمام اتصالات پارامتر به درستی جایگزین کنند:

DB::table('users')->where('votes', '>', 100)->dumpRawSql();
 
DB::table('users')->where('votes', '>', 100)->ddRawSql();