Programming Tutorial Laravel Database 27 July 2025

10 Query Laravel yang Wajib Dikuasai Developer

10 Query Laravel yang Wajib Dikuasai Developer
Bagikan:

Buat kamu yang belajar Laravel, menguasai query database itu penting banget. Kalau query-nya ngasal, aplikasi bisa jadi lemot dan bikin user kesal. Laravel Eloquent memang mudah dipakai, tapi tetap harus tahu cara yang benar.

Dari pengalaman ngoding Laravel, ada 10 query dasar yang sering banget dipake dan wajib dikuasai. Ini bukan cuma soal nulis kode, tapi juga kapan harus pakai yang mana.

Yuk kita bahas satu-satu dengan contoh sederhana yang bisa langsung dicoba!

Eager Loading - Cara Ambil Data Relasi yang Benar

Query pertama yang harus dikuasai adalah eager loading. Ini buat ngambil data yang punya relasi tanpa bikin database kewalahan.

Masalah yang Sering Terjadi

// ❌ Cara yang salah - bikin database kerja keras
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->user->name; // Tiap post query database lagi
}

Kalau ada 100 post, database akan diquery 101 kali! (1 kali ambil posts + 100 kali ambil user)

Cara yang Benar

// ✅ Pakai with() - cuma 2 kali query
$posts = Post::with('user')->get();
foreach ($posts as $post) {
    echo $post->user->name; // Data user udah ada
}

Ambil Banyak Relasi Sekaligus

// Ambil post sama user dan category-nya
$posts = Post::with(['user', 'category'])->get();

Ambil Relasi Bersyarat

// Cuma ambil user yang aktif
$posts = Post::with(['user' => function ($query) {
    $query->where('status', 'active');
}])->get();

Dengan eager loading, aplikasi jadi lebih cepat karena database gak perlu kerja berkali-kali.

Scopes - Bikin Query yang Bisa Dipakai Berulang

Scopes itu kayak shortcut buat query yang sering dipake. Jadi gak perlu nulis ulang terus-terusan.

Buat Scope di Model

class Post extends Model
{
    // Scope buat post yang udah dipublish
    public function scopePublished($query)
    {
        return $query->where('status', 'published');
    }
    
    // Scope buat post dari author tertentu
    public function scopeByAuthor($query, $authorId)
    {
        return $query->where('user_id', $authorId);
    }
    
    // Scope buat post terbaru
    public function scopeRecent($query, $days = 7)
    {
        return $query->where('created_at', '>=', now()->subDays($days));
    }
}

Cara Pakai Scope

// Pakai satu scope
$posts = Post::published()->get();

// Gabung beberapa scope
$posts = Post::published()
            ->recent(30)
            ->byAuthor(1)
            ->get();

// Gabung dengan where biasa
$posts = Post::published()
            ->where('category_id', 2)
            ->orderBy('created_at', 'desc')
            ->get();

Scope yang Fleksibel

public function scopeFilter($query, $filters)
{
    if (isset($filters['status'])) {
        $query->where('status', $filters['status']);
    }
    
    if (isset($filters['search'])) {
        $query->where('title', 'like', '%' . $filters['search'] . '%');
    }
    
    if (isset($filters['category'])) {
        $query->where('category_id', $filters['category']);
    }
    
    return $query;
}

// Cara pakai
$posts = Post::filter(request()->only('status', 'search', 'category'))->get();

Dengan scope, kode jadi lebih rapi dan gak perlu copy-paste query yang sama.

Query Hitung-hitungan untuk Dashboard

Query ini berguna buat bikin dashboard atau laporan sederhana.

Hitung Data Dasar

// Hitung jumlah post
$totalPosts = Post::count();

// Hitung post yang dipublish
$publishedPosts = Post::where('status', 'published')->count();

// Jumlah total views
$totalViews = Post::sum('view_count');

// Rata-rata rating
$averageRating = Review::avg('rating');

// Post tertua dan terbaru
$oldestPost = Post::min('created_at');
$newestPost = Post::max('created_at');

Kelompokkan Data

// Hitung post per kategori
$postsByCategory = Post::select('category_id')
    ->selectRaw('count(*) as total')
    ->groupBy('category_id')
    ->get();

// Penjualan per bulan
$monthlySales = Sale::selectRaw('MONTH(created_at) as month')
    ->selectRaw('SUM(amount) as total')
    ->groupBy('month')
    ->get();

Filter Hasil Kelompok

// Kategori yang punya lebih dari 10 post
$popularCategories = Post::select('category_id')
    ->selectRaw('count(*) as posts_count')
    ->groupBy('category_id')
    ->having('posts_count', '>', 10)
    ->get();

Query Bersyarat dengan when()

Method when() berguna banget buat bikin query yang dinamis. Jadi bisa berubah tergantung kondisi.

Query Sederhana dengan Kondisi

$posts = Post::query()
    ->when(request('search'), function ($query, $search) {
        $query->where('title', 'like', '%' . $search . '%');
    })
    ->when(request('category'), function ($query, $category) {
        $query->where('category_id', $category);
    })
    ->get();

Beberapa Kondisi Sekaligus

$users = User::query()
    ->when(request('role'), function ($query, $role) {
        $query->where('role', $role);
    })
    ->when(request('active_only'), function ($query) {
        $query->where('status', 'active');
    })
    ->get();

Kondisi dengan Pilihan

$posts = Post::query()
    ->when(auth()->user()->role == 'admin', 
        function ($query) {
            // Admin bisa lihat semua
            return $query;
        },
        function ($query) {
            // User biasa cuma lihat punya sendiri
            return $query->where('user_id', auth()->id());
        }
    )
    ->get();

Query Relasi yang Mudah Dipahami

Query relasi itu buat ngambil data yang punya hubungan dengan tabel lain.

Cari Data yang Punya Relasi

// Post yang punya komentar
$postsWithComments = Post::has('comments')->get();

// Post yang punya lebih dari 5 komentar
$popularPosts = Post::has('comments', '>', 5)->get();

// Post yang dikomentar user tertentu
$posts = Post::whereHas('comments', function ($query) {
    $query->where('user_id', 1);
})->get();

Hitung Jumlah Relasi

// Ambil post beserta jumlah komentarnya
$posts = Post::withCount('comments')->get();

// Hitung beberapa relasi sekaligus
$posts = Post::withCount(['comments', 'likes'])->get();

// Hitung komentar terbaru (7 hari terakhir)
$posts = Post::withCount([
    'comments as recent_comments_count' => function ($query) {
        $query->where('created_at', '>', now()->subDays(7));
    }
])->get();

Cek Apakah Data Ada

// Cek apakah user punya post
$hasPost = Post::where('user_id', 1)->exists();

// Lebih cepat daripada count() > 0
if (User::where('email', $email)->exists()) {
    echo "Email udah ada";
}

Filter Berdasarkan Relasi

// User yang punya post dalam 30 hari terakhir
$activeUsers = User::whereHas('posts', function ($query) {
    $query->where('created_at', '>', now()->subDays(30));
})->get();

Raw Query untuk Kasus Khusus

Kadang butuh query mentah SQL buat hal-hal yang kompleks.

Hitung dengan Rumus

// Hitung engagement score
$posts = Post::selectRaw('*, (view_count + comment_count * 2) as engagement_score')
    ->orderBy('engagement_score', 'desc')
    ->get();

// Format tanggal
$sales = Sale::selectRaw('DATE(created_at) as sale_date')
    ->selectRaw('SUM(amount) as total')
    ->groupBy('sale_date')
    ->get();

Kondisi Kompleks

// Cari berdasarkan rentang hari
$posts = Post::whereRaw('DATEDIFF(NOW(), created_at) BETWEEN ? AND ?', [7, 30])
    ->get();

Update dengan Perhitungan

// Tambah view count
Post::where('id', 1)->update([
    'view_count' => DB::raw('view_count + 1')
]);

Pagination - Bagi Data Jadi Halaman

Pagination berguna buat bagi data jadi beberapa halaman, jadi gak loading semua sekaligus.

Pagination Dasar

// Pagination biasa
$posts = Post::paginate(15);

// Pagination sederhana (cuma Next/Previous)
$posts = Post::simplePaginate(15);

// Jumlah per halaman dari request
$perPage = request('per_page', 15);
$posts = Post::paginate($perPage);

Pagination dengan Filter

$posts = Post::where('status', 'published')
    ->when(request('search'), function ($query, $search) {
        $query->where('title', 'like', '%' . $search . '%');
    })
    ->orderBy('created_at', 'desc')
    ->paginate(10);

Subquery - Query di Dalam Query

Subquery berguna buat ambil data yang lebih kompleks dalam satu kali jalan.

Ambil Data Tambahan

// Ambil user dengan judul post terbarunya
$users = User::addSelect([
    'latest_post_title' => Post::select('title')
        ->whereColumn('user_id', 'users.id')
        ->orderBy('created_at', 'desc')
        ->limit(1)
])->get();

Filter dengan Subquery

// User yang punya post dengan views > 100
$users = User::whereIn('id', function ($query) {
    $query->select('user_id')
          ->from('posts')
          ->where('view_count', '>', 100);
})->get();

Cek Keberadaan dengan Subquery

// Post yang belum ada komentarnya
$posts = Post::whereNotExists(function ($query) {
    $query->select(DB::raw(1))
          ->from('comments')
          ->whereColumn('posts.id', 'comments.post_id');
})->get();

Operasi Banyak Data Sekaligus

Kalau mau insert, update, atau delete banyak data, lebih baik sekaligus daripada satu-satu.

Insert Banyak Data

$posts = [];
for ($i = 0; $i < 100; $i++) {
    $posts[] = [
        'title' => 'Post ' . $i,
        'content' => 'Isi post ' . $i,
        'user_id' => 1,
        'created_at' => now(),
        'updated_at' => now(),
    ];
}

// Insert semua sekaligus - lebih cepat
Post::insert($posts);

Delete Banyak Data

// Delete berdasarkan array ID
Post::whereIn('id', [1, 2, 3, 4, 5])->delete();

// Soft delete banyak data
Post::whereIn('id', $postIds)->update(['deleted_at' => now()]);

Insert atau Update

$data = [
    ['email' => 'john@example.com', 'name' => 'John'],
    ['email' => 'jane@example.com', 'name' => 'Jane'],
];

// Kalau email udah ada, update name. Kalau belum, insert baru
User::upsert($data, 'email', ['name']);

Database Transaction - Jaga Konsistensi Data

Transaction berguna buat pastikan kalau ada beberapa operasi database yang harus sukses semua atau gagal semua.

Transaction Sederhana

DB::transaction(function () {
    // Buat user baru
    $user = User::create([
        'name' => 'John Doe',
        'email' => 'john@example.com',
    ]);
    
    // Buat profile untuk user tersebut
    Profile::create([
        'user_id' => $user->id,
        'bio' => 'Laravel developer',
    ]);
    
    // Kalau ada error di manapun, semua dibatalkan
});

Transaction Manual

DB::beginTransaction();

try {
    $order = Order::create($orderData);
    
    foreach ($items as $item) {
        OrderItem::create([
            'order_id' => $order->id,
            'product_id' => $item['product_id'],
            'quantity' => $item['quantity'],
        ]);
        
        // Kurangi stok
        Product::where('id', $item['product_id'])
            ->decrement('stock', $item['quantity']);
    }
    
    DB::commit(); // Simpan semua perubahan
    
} catch (Exception $e) {
    DB::rollback(); // Batalkan semua perubahan
    throw $e;
}

Transaction yang Return Value

$order = DB::transaction(function () {
    $order = Order::create($orderData);
    
    $this->processPayment($order);
    $this->sendEmail($order);
    
    return $order; // Bisa return value dari transaction
});

Nah, itu dia 10 query Laravel yang wajib dikuasai! Dengan menguasai query-query ini, kamu bisa bikin aplikasi Laravel yang lebih cepat dan efisien.

Yang penting diingat:

  • Selalu gunakan eager loading buat hindari N+1 problem
  • Pakai scope buat query yang sering diulang
  • Manfaatkan pagination buat data yang banyak
  • Gunakan transaction buat operasi yang butuh konsistensi

Selamat coding dengan Laravel!