پایگاه داده: Query Builder
- معرفی
- اجرای کوئری های پایگاه داده
- بیانیه ها را انتخاب کنید
- عبارات خام
- می پیوندد
- اتحادیه ها
- عبارات اصلی Where
- بندهای پیشرفته Where
- سفارش، گروه بندی، محدودیت و افست
- عبارت های شرطی
- درج بیانیه ها
- به روز رسانی بیانیه ها
- حذف بیانیه ها
- قفل بدبینانه
- اشکال زدایی
معرفی
سازنده پرس و جو پایگاه داده لاراول یک رابط راحت و روان برای ایجاد و اجرای پرس و جوهای پایگاه داده ارائه می دهد. می توان از آن برای انجام اکثر عملیات پایگاه داده در برنامه کاربردی خود استفاده کرد و با تمام سیستم های پایگاه داده پشتیبانی شده لاراول کاملاً کار می کند.
سازنده پرس و جو لاراول از اتصال پارامتر 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 usersWHERE 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 postsWHERE 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 userswhere 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();