クエリビルダー
- 集計
- Unions
- Where ステートメント
- パラメーターのグループ化
- #Where Exists 構文
- JSON Where 構文
- 順序付け、グループ化、制限、オフセット
- ##条件文
- 挿入 #Update
- JSON を更新
- #自動インクリメントと自動マイナス
- 削除
- 悲観的ロック
- ##
はじめに
Laravel のデータベース クエリ ビルダーは、データベース クエリを作成および実行するための便利なインターフェイスを提供します。これを使用すると、アプリケーションでほとんどのデータベース操作を実行でき、サポートされているすべてのデータベース システムで実行できます。
Laravel のクエリビルダーは、PDO パラメーター バインディングを使用して、アプリケーションを SQL インジェクション攻撃から保護します。したがって、バインディングとして渡された文字列をサニタイズする必要はありません。
#結果の取得データ テーブルからすべての行を取得DB
で
tableメソッドを使用してクエリを開始できます。
tableメソッドは、指定されたテーブルのクエリ ビルダー インスタンスを返します。これにより、クエリに対してさらに多くの制約を連鎖させることができ、最後に
getメソッドを使用して結果を取得できます。
<?php namespace App\Http\Controllers; use Illuminate\Support\Facades\DB; use App\Http\Controllers\Controller; class UserController extends Controller{ /** * 显示所有应用程序的用户列表。 * * @return Response */ public function index() { $users = DB::table('users')->get(); return view('user.index', ['users' => $users]); } }
get
メソッドは、
Illuminate\Support\Collectionを含む結果を返します。各結果は
PHPオブジェクトのインスタンスです。オブジェクトのプロパティとしてフィールドにアクセスして、各列の値にアクセスできます。
foreach ($users as $user) { echo $user->name; }
データ テーブルから単一の行または列を取得しますデータ テーブルから単一の行または列を取得する必要があります データ行を取得するには、first
メソッドを使用できます。このメソッドは、
StdClassオブジェクトを返します:
$user = DB::table('users')->where('name', 'John')->first(); echo $user->name;
データの行全体が必要ない場合は、value
メソッドを使用して単一の値を取得できます。記録から。このメソッドはフィールドの値を直接返します。
$email = DB::table('users')->where('name', 'John')->value('email');
列の値を取得する単一の列値を含むコレクションを取得したい場合は、次のようにします。pluck
メソッドを使用できます。次の例では、ロール テーブル内のタイトルのコレクションを取得します:
$titles = DB::table('roles')->pluck('title'); foreach ($titles as $title) { echo $title; }
返されたコレクションのフィールドにカスタム キー値を指定することもできます:$roles = DB::table('roles')->pluck('title', 'name'); foreach ($roles as $name => $title) { echo $title; }
チャンク結果
数千のデータベース レコードを処理する必要がある場合は、
chunk
メソッドの使用を検討してください。このメソッドは、一度に結果セットの小さな部分を取得し、それを処理のためにClosure
関数に渡します。この方法は、数千のデータを処理するアーティザン コマンドを作成する場合に便利です。たとえば、users
テーブル データ全体を、一度に 100 レコードを処理する小さな部分に分割できます。DB::table('users')->orderBy('id')->chunk(100, function ($users) { foreach ($users as $user) { // } });
これを行うには、
closure で ## を返します。
#false: チャンク化された結果の継続的な取得を終了するには:
DB::table('users')->orderBy('id')->chunk(100, function ($users) { // Process the records... return false; });
結果をチャンク化するときにデータベース レコードを更新する場合、チャンク化された結果は予期される返される結果と一致しない可能性があります。したがって、チャンク内のレコードを更新する場合は、chunkById
メソッドを使用するのが最善です。このメソッドは、レコードの主キーに基づいて結果を自動的にページ分割します:
DB::table('users')->where('active', false) ->chunkById(100, function ($users) { foreach ($users as $user) { DB::table('users') ->where('id', $user->id) ->update(['active' => true]); } });
{ヒント} ブロックのコールバック内のレコードを更新または削除するとき、主キーまたは外部キーへの変更はブロックに影響を与える可能性があります。クエリです。これにより、チャンク化された結果にレコードが含まれない可能性があります。
集計クエリ ビルダーは、count # などのさまざまな集計メソッドも提供します。 ##、
max
、min
、avg
、およびsum
。クエリを作成した後に任意のメソッドを呼び出すことができます:
もちろん、これらの集計メソッドを他のクエリ ステートメントと組み合わせることもできます:$users = DB::table('users')->count(); $price = DB::table('orders')->max('price');
$price = DB::table('orders') ->where('finalized', 1) ->avg('price');
レコードが存在するかどうかを確認するクエリ条件の結果が存在するかどうかを判断するには、
countメソッドを使用するほかに、
SelectsSelect ステートメントを指定しますOfもちろん、そうでない場合もあります。データベース テーブルからすべての列を取得することが常に望ましいとは限りません。exists
およびdoesntExist
を使用することもできます。メソッド:return DB::table('orders')->where('finalized', 1)->exists(); return DB::table('orders')->where('finalized', 1)->doesntExist();
select
メソッドを使用すると、指定したフィールドをクエリするためのselect
クエリ ステートメントをカスタマイズできます。
$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();
ネイティブ式 クエリでネイティブ式を使用する必要がある場合があります。
DB::raw
:$users = DB::table('users') ->select(DB::raw('count(*) as user_count, status')) ->where('status', '<>', 1) ->groupBy('status') ->get();
{ヒント} を使用して生の式を作成できます。生の式は文字列としてクエリに挿入されるため、注意が必要です。 SQL インジェクションの脆弱性の作成を避けるため。
代わりに次のメソッドを使用できますDB::raw、クエリのさまざまな部分にネイティブ表現を挿入します。
##havingRaw / orHavingRawselectRaw
selectRaw
メソッドは、select(DB::raw(...))
の代わりに使用できます。このメソッドの 2 番目のパラメーターはオプションであり、値はバインドされたパラメーターの配列です:$orders = DB::table('orders') ->selectRaw('price * ? as price_with_tax', [1.0825]) ->get();
whereRaw / orWhereRaw
# #whereRaw
メソッドと
orWhereRawメソッドは、ネイティブの
whereをクエリに挿入します。これら 2 つのメソッドの 2 番目のパラメーターは依然としてオプションであり、値は引き続きバインドされたパラメーターの配列です:
$orders = DB::table('orders') ->whereRaw('price > IF(state = "TX", ?, 100)', [200]) ->get();
メソッドと#havingRaw
orHavingRaw
メソッドを使用して、生の文字列を
havingステートメントの値に設定できます:
$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();
JoinsInner Join Clauseクエリ コンストラクターを記述することもできます。
join
メソッド。基本的な「内部結合」を実行するには、クエリ ビルダー インスタンスで
join
メソッドを使用します。
joinメソッドに渡される最初のパラメータは結合するテーブルの名前であり、他のパラメータは結合を指定するフィールド制約を使用します。単一のクエリで複数のデータ テーブルを結合することもできます。
$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
メソッドを使用できます。これら 2 つのメソッドの使用法は、
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();
Cross Join ステートメント
crossJoin
メソッドを使用します。接続するテーブルの名前を「クロス接続」と呼びます。クロス結合では、最初のテーブルと結合されたテーブルの間にデカルト積が生成されます。$users = DB::table('sizes') ->crossJoin('colours') ->get();
高度な結合ステートメントより高度な結合ステートメントを指定できます。たとえば、
closure
をjoin
メソッドを使用できます。これらのメソッドは、列と列ではなく、列と値を比較します。メソッドの 2 番目のパラメーターとして渡します。この
Closureは
JoinClause
オブジェクトを受け取り、それによって
joinステートメントで指定された制約を指定します。接続で「where」スタイルのステートメントを使用する場合は、接続で
whereメソッドと
orWhereDB::table('users') ->join('contacts', function ($join) { $join->on('users.id', '=', 'contacts.user_id')->orOn(...); }) ->get();
Subjoin query
joinSub、を使用できます。 leftJoinSub
メソッドとrightJoinSub
上記のクエリは次の SQL ステートメントを生成します:メソッドは、クエリをサブクエリとして結合します。各メソッドは、サブクエリ、テーブル エイリアス、および関連するフィールドを定義するクロージャの 3 つのパラメータを受け取ります。
結合
クエリ ビルダーは、2 つのクエリを「結合」するためのショートカットも提供します。たとえば、クエリを作成し、
union
メソッドを使用して 2 番目のクエリと結合できます。DB::table('users') ->join('contacts', function ($join) { $join->on('users.id', '=', 'contacts.user_id') ->where('contacts.user_id', '>', 5); }) ->get();
{ヒント}
unionAll ## を使用することもできます。 # 方法、使い方
union方法は同じです。
#Where ステートメント単純な Where ステートメントクエリ インスタンスを構築する際には、
where
メソッドを使用できます。where
を呼び出す最も基本的な方法は、3 つのパラメーターを渡すことです。最初のパラメーターは列名、2 番目のパラメーターはデータベース システムでサポートされている演算子、3 番目のパラメーターは比較される列です。価値。たとえば、次のクエリは、「votes」フィールドの値が 100 に等しいことを確認します。
$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($join) { $join->on('users.id', '=', 'latest_posts.user_id'); }) ->get();
便宜上、単に列の値が 100 であるかどうかを比較する場合、指定された値と等しい場合は、その値を
whereメソッドの 2 番目のパラメータとして直接使用します。
を記述することもできます。 where
もちろん、他の演算子を使用して$first = DB::table('users') ->whereNull('first_name');$users = DB::table('users') ->whereNull('last_name') ->union($first) ->get();
句:
where
条件配列を$users = DB::table('users')->where('votes', '=', 100)->get();
関数に渡すこともできます:
$users = DB::table('users')->where('votes', 100)->get();
Or ステートメントwhere 制約を連鎖させることもできます。クエリに
または句を追加することもできます。
orWhere
メソッドは、where
メソッドと同じパラメータを受け取ります:$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 ステートメント
whereBetween
whereBetween
このメソッドは、フィールド値が指定された 2 つの値の間にあるかどうかを検証します。$users = DB::table('users')->where([ ['status', '=', '1'], ['subscribed', '<>', '1'], ])->get();
whereNotBetween
whereNotBetween
メソッドは、フィールド値が指定された 2 つの値の範囲外であるかどうかを検証します:$users = DB::table('users') ->where('votes', '>', 100) ->orWhere('name', 'John') ->get();
whereIn / whereNotIn
whereIn
メソッド検証フィールドの値は、指定された配列に存在する必要があります。:$users = DB::table('users') ->whereBetween('votes', [1, 100])->get();
whereNotIn
メソッド検証の値field 指定された配列内に存在してはなりません:$users = DB::table('users') ->whereNotBetween('votes', [1, 100]) ->get();
whereNull / whereNotNull
#whereNull
このメソッドは、指定されたフィールドがNULL である必要があることを検証します。
:$users = DB::table('users') ->whereIn('id', [1, 2, 3]) ->get();
whereNotNull
このメソッドは、指定されたフィールドがNULL
:$users = DB::table('users') ->whereNotIn('id', [1, 2, 3]) ->get();
whereDate / whereMonth / であってはいけないことを検証します。 whereDay / where Year / whereTime
whereDate
メソッドは、フィールド値を指定された日付と比較するために使用されます。$users = DB::table('users') ->whereNull('updated_at') ->get();
whereMonth
メソッドは次のとおりです。フィールド値を指定された月と比較するために使用されます:$users = DB::table('users') ->whereNotNull('updated_at') ->get();
whereDay
メソッドは、フィールド値を指定された月と比較するために使用されます:$users = DB::table('users') ->whereDate('created_at', '2018-09-08') ->get();
whereyear
メソッド フィールド値と指定された年を比較するために使用されます:$users = DB::table('users') ->whereMonth('created_at', '9') ->get();
whereTime
このメソッドは、フィールド値と指定された時刻 (時間、分と秒):$users = DB::table('users') ->whereDay('created_at', '8') ->get();
whereColumn
whereColumn
このメソッドは、2 つのフィールドの値が等しいかどうかを比較するために使用されます。 :$users = DB::table('users') ->whereYear('created_at', '2018') ->get();
比較演算子を渡すこともできます:
$users = DB::table('users') ->whereTime('created_at', '=', '11:20:45') ->get();
whereColumn
and
演算子を使用してリンクされた配列を渡すこともできます:$users = DB::table('users') ->whereColumn('first_name', 'last_name') ->get();
パラメータのグループ化
「where doesn't」やネストされたパラメータなど、より高度な where 句を作成する必要がある場合があります。グループ化。 Laravel のクエリ ビルダーでもこれを処理できます。次に、括弧内で制約をグループ化する例を見てみましょう。
$users = DB::table('users') ->whereColumn('updated_at', '>', 'created_at') ->get();
クエリ構成が
Closure
writewhere
メソッドによって構築されていることがわかります。 制約するコンテナグループ。このClosure
は、含める必要がある制約を設定するために使用できるクエリ インスタンスを受け取ります。上記の例では、次の SQL が生成されます:$users = DB::table('users') ->whereColumn([ ['first_name', '=', 'last_name'], ['updated_at', '>', 'created_at'] ])->get();
#Where Exists ステートメント{ヒント} 予期しないアプリケーションのグローバルな影響を避けるために、
orWhere
を使用してこのグループを呼び出す必要があります。whereExists
メソッドを使用すると、
where assignsSQL を使用できます。声明 。
whereExistsメソッドは、
Closureパラメータを受け入れます。
whereExistsメソッドは、Closure パラメータを受け入れます。このクロージャは、
exists を定義できるクエリ ビルダー インスタンスを取得します。文内のクエリ:
DB::table('users') ->where('name', '=', 'John') ->where(function ($query) { $query->where('votes', '>', 100) ->orWhere('title', '=', 'Admin'); }) ->get();
select * from users where name = 'John' and (votes > 100 or title = 'Admin')
JSON Where ステートメント
Laravel は、JSON 型フィールドのクエリもサポートしています (JSON 型をサポートするデータベースのみ)。現在、この機能は MySQL 5.7、PostgreSQL、SQL Server 2016、および SQLite 3.9.0 (JSON1 拡張子 を含む) のみをサポートしています。
->
演算子を使用して JSON データをクエリします:DB::table('users') ->whereExists(function ($query) { $query->select(DB::raw(1)) ->from('orders') ->whereRaw('orders.user_id = users.id'); }) ->get();
whereJsonContains
を使用して JSON 配列をクエリすることもできます:select * from users where exists ( select 1 from orders where orders.user_id = users.id)
MySQL および PostgreSQL
whereJsonContains
複数の値をサポートできます:$users = DB::table('users') ->where('options->language', 'en') ->get();$users = DB::table('users') ->where('preferences->dining->meal', 'salad') ->get();
whereJsonLength
を使用して JSON 配列の長さをクエリできます:$users = DB::table('users') ->whereJsonContains('options->languages', 'en') ->get();
##順序付け、グループ化、制限、オフセットorderByorderBy
メソッドを使用すると、次のことが可能になります。 to pass 指定されたフィールドによって結果セットを並べ替えます。
orderByの最初のパラメーターは並べ替えるフィールドにする必要があり、2 番目のパラメーターは並べ替えの方向を制御します (
ascまたは
desc:
$users = DB::table('users') ->whereJsonContains('options->languages', ['en', 'de']) ->get();
latest/oldestlatest
メソッドと
oldestメソッドを使用すると、日付で簡単に並べ替えることができます。デフォルトでは、
created_at列を並べ替え基準として使用します。もちろん、カスタム列名を渡すこともできます。
$users = DB::table('users') ->whereJsonLength('options->languages', 0) ->get();$users = DB::table('users') ->whereJsonLength('options->languages', '>', 1) ->get();
inRandomOrderinRandomOrder
メソッドを使用して、結果をランダムに並べ替えます。たとえば、このメソッドを使用して、ランダムなユーザーを見つけることができます。
$users = DB::table('users') ->orderBy('name', 'desc') ->get();
groupBy / gettinggroupBy
および
havingメソッドを使用すると、結果をグループ化できます。
havingメソッドの使用法は、
whereメソッドとよく似ています。
$user = DB::table('users') ->latest() ->first();
複数のパラメータをgroupBy
havingメソッドに渡すことができます。 ##
より高度な$randomUser = DB::table('users') ->inRandomOrder() ->first();
構文については、
havingRaw
メソッドを参照してください。
skip / take返される結果の数を制限したり、指定した数の結果をスキップするには、
skipと # を使用できます。 ## take
メソッド:
$users = DB::table('users') ->groupBy('account_id') ->having('account_id', '>', 100) ->get();
または、
limit およびoffset
メソッド:
$users = DB::table('users') ->groupBy('first_name', 'status') ->having('account_id', '>', 100) ->get();
を使用することもできます。
条件文
特定の条件が true の場合にのみクエリを実行する句が必要な場合があります。たとえば、指定された値がリクエストに存在する場合にのみ
where
ステートメントを適用できます。これを行うには、when
メソッドを使用します。$users = DB::table('users')->skip(10)->take(5)->get();
when
このメソッドは、最初のパラメータがtrue
の場合にのみ、指定されたクロージャを実行します。バッグ。最初のパラメータがfalse
の場合、このクロージャは実行されません。別のクロージャを
when
メソッドの 3 番目のパラメータとして渡すことができます。このクロージャは、最初のパラメータがfalse
の場合に実行されます。この機能の使用方法を説明するために、クエリのデフォルトの順序を設定しましょう:$users = DB::table('users') ->offset(10) ->limit(5) ->get();
INSERT
Query構築 プロセッサは、データベースにレコードを挿入するための
insert
メソッドも提供します。insert
メソッドは、挿入操作のためにフィールド名とフィールド値を配列の形式で受け取ります。$role = $request->input('role');$users = DB::table('users') ->when($role, function ($query, $role) { return $query->where('role_id', $role); }) ->get();
配列を
insert
メソッドに渡すこともできます。テーブルに複数のレコードを挿入します。 Medium$sortBy = null;$users = DB::table('users') ->when($sortBy, function ($query, $sortBy) { return $query->orderBy($sortBy); }, function ($query) { return $query->orderBy('name'); }) ->get();
自動インクリメント ID
データ テーブルに自動インクリメント ID がある場合は、
insertGetId
メソッドを使用してレコードを挿入し、ID 値を返します。DB::table('users')->insert( ['email' => 'john@example.com', 'votes' => 0]);
#更新もちろん、クエリ ビルダーはデータベースにレコードを挿入するだけでなく、次のことも行うことができます。{Note} PostgreSQL を使用する場合、
insertGetId
メソッドはデフォルトでid
を名前として使用します。自動インクリメントフィールド。別の「シーケンス」から ID を取得したい場合は、フィールド名を 2 番目のパラメーターとしてinsertGetId
メソッドに渡すことができます。update
メソッドも渡します。既存のレコードを更新します。
updateメソッドは
insertメソッドと同じで、更新するフィールドと値を含む配列を受け取ります。
where句を使用して
updateクエリを制限できます。
DB::table('users')->insert([ ['email' => 'taylor@example.com', 'votes' => 0], ['email' => 'dayle@example.com', 'votes' => 0] ]);
Update または addデータベース内の既存のレコードを更新するか、一致するレコードが存在しない場合は作成します。この場合、updateOrInsert
メソッドを使用できます。
updateOrInsertこのメソッドは、レコードを検索するための条件配列と、更新するレコードを含むキーと値のペアの配列という 2 つのパラメーターを受け入れます。
updateOrInsert
このメソッドはまず、最初のパラメーターのキーと値のペアを使用して、一致するデータベース レコードの検索を試みます。レコードが存在する場合は、2 番目のパラメーターの値を使用してレコードを更新します。レコードが見つからない場合は、新しいレコードが挿入され、更新されたデータは 2 つの配列のコレクションになります:
$id = DB::table('users')->insertGetId( ['email' => 'john@example.com', 'votes' => 0] );
JSON フィールドの更新
JSON フィールドを更新するときは、
->
構文を使用して、JSON オブジェクト内の対応する値にアクセスできます。この操作は MySQL 5.7 のみをサポートします:DB::table('users') ->where('id', 1) ->update(['votes' => 1]);
インクリメントとデクリメント
クエリ コンストラクターには、特定のフィールドをインクリメントまたはデクリメントするための便利なメソッドも用意されています。この方法では、
update
ステートメントを手動で記述するよりも表現力豊かで簡潔なインターフェイスが提供されます。両方のメソッドは、少なくとも 1 つのパラメータ、つまり変更が必要な列を受け取ります。 2 番目のパラメータはオプションで、列の増減量を制御します:
DB::table('users') ->updateOrInsert( ['email' => 'john@example.com', 'name' => 'John'], ['votes' => '2'] );
操作中に更新するフィールドを指定することもできます:
DB::table('users') ->where('id', 1) ->update(['options->enabled' => true]);
#Deleteクエリ ビルダーは、delete
メソッドを使用してテーブルからレコードを削除することもできます。
deleteを使用する前に、
where句を追加して
deleteを制約することができます。 構文:
DB::table('users')->increment('votes'); DB::table('users')->increment('votes', 5); DB::table('users')->decrement('votes'); DB::table('users')->decrement('votes', 5);
テーブルをクリアする必要がある場合は、次のようにすることができます。truncate
メソッドを使用すると、すべての行が削除され、自動インクリメントされる ID がゼロにリセットされます:
DB::table('users')->increment('votes', 1, ['name' => 'John']);
Pessimistic lock クエリ ビルダーには、select
構文での「悲観的ロック」の実装に役立ついくつかの関数も含まれています。クエリに「共有ロック」を実装する場合は、
sharedLockメソッドを使用できます。共有ロックにより、トランザクションがコミットされるまで、選択されたデータ列が改ざんされることが防止されます。
DB::table('users')->delete(); DB::table('users')->where('votes', '>', 100)->delete();
あるいは、lockForUpdate
メソッドを使用することもできます。 「更新」ロックを使用すると、他の共有ロックによって行が変更または選択されるのを防ぐことができます。
DB::table('users')->truncate();
この記事は、