10 Query Laravel yang Wajib Dikuasai Developer
ProgrammingTutorialLaravelDatabase#laravel#eloquent#database#query

10 Query Laravel yang Wajib Dikuasai Developer

A
Abd. Asis
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

PHPPHP
// ❌ 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

PHPPHP
// ✅ 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

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

Ambil Relasi Bersyarat

PHPPHP
// 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

PHPPHP
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

PHPPHP
// 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

PHPPHP
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

PHPPHP
// 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

PHPPHP
// 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

PHPPHP
// 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

PHPPHP
$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

PHPPHP
$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

PHPPHP
$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

PHPPHP
// 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

PHPPHP
// 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

PHPPHP
// 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

PHPPHP
// 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

PHPPHP
// 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

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

Update dengan Perhitungan

PHPPHP
// 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

PHPPHP
// 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

PHPPHP
$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

PHPPHP
// 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

PHPPHP
// 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

PHPPHP
// 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

PHPPHP
$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

PHPPHP
// 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

PHPPHP
$data = [
    ['email' => '[email protected]', 'name' => 'John'],
    ['email' => '[email protected]', '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

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

Transaction Manual

PHPPHP
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

PHPPHP
$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!

Abd. Asis
Ditulis oleh
Abd. Asis

Software Developer dari Madura. Menulis tentang PHP, Laravel, dan pengembangan web modern dalam Bahasa Indonesia.