ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
Query Builder の基本
DB::table() から始めるメソッドチェーン形式で SQL を組み立てます:
use Illuminate\Support\Facades\DB;
// SELECT * FROM users WHERE active = 1
$users = DB::table('users')
->where('active', 1)
->get();
// SELECT id, name FROM users WHERE age >= 20 ORDER BY name LIMIT 10
$users = DB::table('users')
->select('id', 'name')
->where('age', '>=', 20)
->orderBy('name')
->limit(10)
->get();
// 単一行 / 単一カラム
$user = DB::table('users')->where('id', 1)->first();
$name = DB::table('users')->where('id', 1)->value('name');
$count = DB::table('users')->count();
WHERE 句のバリエーション
| メソッド | 生成される SQL |
|---|---|
where('age', '>', 20) | age > 20 |
whereIn('id', [1,2,3]) | id IN (1,2,3) |
whereBetween('age', [20,30]) | age BETWEEN 20 AND 30 |
whereNull('deleted_at') | deleted_at IS NULL |
whereExists(function ($q) {...}) | EXISTS (SELECT ...) |
orWhere('email', $x) | OR email = ? |
whereRaw('YEAR(created_at) = ?', [2026]) | 生 SQL(パラメータバインド) |
JOIN / GROUP BY / HAVING
// 内部結合 + 集計
$stats = DB::table('users')
->join('orders', 'users.id', '=', 'orders.user_id')
->select('users.name', DB::raw('SUM(orders.amount) AS total'))
->groupBy('users.id', 'users.name')
->having('total', '>', 10000)
->orderByDesc('total')
->get();
// 左外部結合
$users = DB::table('users')
->leftJoin('profiles', 'users.id', '=', 'profiles.user_id')
->select('users.*', 'profiles.bio')
->get();
// サブクエリ join
$latest = DB::table('logins')
->select('user_id', DB::raw('MAX(login_at) AS last'))
->groupBy('user_id');
$users = DB::table('users')
->joinSub($latest, 'l', fn($j) => $j->on('users.id', '=', 'l.user_id'))
->select('users.name', 'l.last')
->get();
selectRaw / whereExists / Union
// selectRaw で集計関数や式を直接書く
$rows = DB::table('orders')
->selectRaw('YEAR(created_at) AS year, SUM(amount) AS total')
->groupBy(DB::raw('YEAR(created_at)'))
->get();
// EXISTS サブクエリ
$users = DB::table('users')
->whereExists(function ($q) {
$q->select(DB::raw(1))
->from('orders')
->whereColumn('orders.user_id', 'users.id')
->where('orders.amount', '>', 10000);
})
->get();
// UNION
$a = DB::table('users')->where('type', 'admin');
$b = DB::table('users')->where('type', 'editor');
$all = $a->unionAll($b)->get();
INSERT / UPDATE / DELETE
// 単一 INSERT
DB::table('users')->insert([
'name' => 'Alice',
'email' => 'alice@example.com',
'created_at' => now(),
]);
// 一括 INSERT
DB::table('users')->insert([
['name' => 'Bob', 'email' => 'bob@example.com'],
['name' => 'Charlie', 'email' => 'charlie@example.com'],
]);
// INSERT して ID を取得
$id = DB::table('users')->insertGetId([
'name' => 'Dan',
'email' => 'dan@example.com',
]);
// UPDATE
$affected = DB::table('users')
->where('id', 1)
->update(['name' => 'Alice Smith']);
// UPSERT(PHP 8 + Laravel 8+)
DB::table('users')->upsert(
[['email' => 'a@x.com', 'name' => 'A'], ['email' => 'b@x.com', 'name' => 'B']],
['email'], // 重複検出キー
['name'] // 更新対象カラム
);
// DELETE
DB::table('users')->where('active', 0)->delete();
生 SQL を実行: DB::select / DB::statement
// SELECT 系
$rows = DB::select('SELECT * FROM users WHERE active = ?', [1]);
// 戻り値が不要なステートメント (CREATE / ALTER / TRUNCATE)
DB::statement('TRUNCATE TABLE logs');
DB::statement('CREATE INDEX idx_email ON users(email)');
// DDL
DB::unprepared('CREATE TABLE backup_users AS SELECT * FROM users');
// プレースホルダ必須(SQL インジェクション対策)
// ❌ 危険
DB::select("SELECT * FROM users WHERE email = '{$email}'");
// ✅ 安全
DB::select('SELECT * FROM users WHERE email = ?', [$email]);
トランザクション
// クロージャ版(例外で自動ロールバック・推奨)
DB::transaction(function () {
DB::table('accounts')->where('id', 1)->decrement('balance', 1000);
DB::table('accounts')->where('id', 2)->increment('balance', 1000);
DB::table('transfers')->insert([
'from' => 1, 'to' => 2, 'amount' => 1000,
]);
});
// 手動制御版
DB::beginTransaction();
try {
// ...
DB::commit();
} catch (\Throwable $e) {
DB::rollBack();
throw $e;
}
// デッドロック時のリトライ回数(第 2 引数)
DB::transaction(function () { /* ... */ }, 3);
SQL インジェクション対策
Query Builder はすべてのパラメータを自動バインドします。whereRaw でも第 2 引数の配列にすればバインドされます:
// ✅ 自動バインド
DB::table('users')->where('email', $email)->get();
// → SELECT * FROM users WHERE email = ?
// バインド: [$email]
// ✅ whereRaw でもバインドできる
DB::table('users')->whereRaw('LOWER(email) = ?', [strtolower($email)])->get();
// ❌ 絶対やってはいけない(文字列連結)
DB::select("SELECT * FROM users WHERE email = '$email'");
Eloquent との使い分け
| 場面 | 推奨 | 理由 |
|---|---|---|
| 1 件取得 → 加工 → 保存 | Eloquent | モデルのビジネスロジックを通す |
| 複雑な集計レポート | Query Builder | SQL を直に書く方が見通し良い |
| 大量バルク INSERT | Query Builder + insert() | Eloquent はモデル生成のオーバヘッドあり |
| リレーション込みの取得 | Eloquent + with() | N+1 回避が容易 |
| 外部 DB の参照 | Query Builder | モデル不要 |
発行された SQL を確認
// toSql() で生 SQL(プレースホルダのまま)
$sql = DB::table('users')->where('id', 1)->toSql();
// → SELECT * FROM users WHERE id = ?
// バインドパラメータ
$bindings = DB::table('users')->where('id', 1)->getBindings();
// → [1]
// クエリログを取る(開発時のみ)
DB::enableQueryLog();
DB::table('users')->get();
dd(DB::getQueryLog());
FAQ
Q: get() と first() と value() の違い
A: get() はコレクション、first() は 1 行(オブジェクト or null)、value('col') は 1 カラムの値のみ。
Q: chunk / chunkById の違い
A: 大量データを分割処理する際、chunk() は OFFSET ベースで重複の可能性あり。chunkById() は主キーで進めるので安全。
Q: Query Builder で N+1 は起きる?
A: Query Builder はそもそもリレーションを自動取得しないので発生しません。Eloquent でのみ with() による Eager Loading が必要です。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
同階層のページ
- インストールと設定
- クイックスタート & チュートリアル(初心者向け)
- クイックスタート & チュートリアル(中級者向け)
- ルーティング
- Bladeテンプレート(ビュー/レイアウト)
- コントローラー
- マイグレーションとテーブル定義
- データベースの設定
- Eloquentモデル (ORM)
- SQLとクエリビルダー
- バリデーション
- .envファイルの設定値へのアクセス
- 動作環境による分岐処理
- configフォルダ配下の設定値へのアクセス
- assetヘルパーを利用したpublicフォルダへのアクセス
- storageフォルダへのアクセス
- アプリケーション名の変更
- メンテナンス
- ログイン画面(認証システム)の作成
- ログインの必須化
- ログインユーザー情報の取得
- ルートの認証化
- 本番サーバーへのデプロイ方法
- 多言語化
- csrf_field
- ファイルのダウンロード
- CSVのアップロードおよび読み込み(maatwebsite/excel)
- ページタイトルの設定
- コマンド一覧
- エラー一覧
- SQLの実行ログ出力方法
- キャッシュのクリア
- Selectの結果の最初もしくは最後に任意の値を追加する方法
- ajaxでPOST通信する際の注意点
- ソーシャルログインの実装
- セッション情報の確認
- ログイン、ユーザー登録、パスワードリセット後のリダイレクト先の変更方法
- redirectやreturn viewにメッセージを付与する方法
- クッキー(cookie)の設定と取得
- クラスの再読み込み
- csrfの有効時間を変更する方法
- ViewComposerを用いてviewに共通の値を付与する方法
- View::shareを用いて共通の値を各ビューに渡す方法
- ミドルウェアを用いた処理の共通化
- Middleware内でAuth::check()などを使用する方法
- Controller以外でリダイレクトする方法
- セッションの値の取得/保存/更新/削除
- $requestの値を変更する方法
- 常時SSL化
- ページング(ページネーション)をする方法
- vue.jsとの連携
- Vue.jsと連携するSPA実行環境構築
- .envの値をvue.jsで参照する方法
- vue.jsを本番環境にリリースする方法
- could not find driver(Windows, MySQL編)
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- SEO タイトル設計とキーワード配置完全ガイド (CTR / LLMO 対応) 2026-06-10 18:13:56
- Vue.js v-bind 完全ガイド (属性 / クラス / スタイル / Composition API) 2026-06-10 18:13:56
- Twitter (X) プラットフォーム完全ガイド 2026 (API / Premium / 競合) 2026-06-10 18:13:56
- PHP 変数スコープ完全ガイド (global / static / use / Arrow Function) 2026-06-10 18:13:56
- jQuery .height() 完全ガイド (innerHeight / outerHeight / box-sizing) 2026-06-10 18:13:56
- WordPress 主要独自関数完全ガイド (Loop / Enqueue / Hook / Conditional Tag) 2026-06-10 18:13:56
- jQuery 要素・値の削除完全ガイド (remove / detach / empty / val) 2026-06-10 18:13:56
- PHP コメント完全ガイド (// / # / /* */ / PHPDoc) 2026-06-10 18:13:56
- PHP 改行出力 (\n / PHP_EOL / nl2br) 完全ガイド 2026-06-10 18:13:56
- JavaScript 確認ダイアログ完全ガイド (confirm / alert / prompt / dialog) 2026-06-10 18:13:56
- UE5 スクリーンショット保存 (Scene Capture) 完全ガイド 2026-06-10 18:12:53
- UE5 Nav Mesh Bounds Volume 完全ガイド 2026-06-10 18:12:53
- EJS テンプレートの共通化 (include) 完全ガイド 2026-06-10 18:12:53
- UE5 カメラ傾き角度制限完全ガイド (Pitch Min/Max) 2026-06-10 18:12:53
- SQLite 完全ガイド (組み込み RDBMS) 2026-06-10 18:12:53
コメントを削除してもよろしいでしょうか?