Query Builder

NexaUI framework menyediakan Query Builder yang kuat dan fleksibel untuk membangun query SQL dengan cara yang lebih ekspresif dan aman.

Pengenalan Query Builder

Query Builder memungkinkan Anda membangun query SQL dengan cara yang lebih terstruktur dan mudah dibaca. Ini juga menyediakan lapisan abstraksi yang membantu mencegah SQL injection.

Keuntungan Query Builder

  • Sintaks yang lebih mudah dibaca dan dipelihara
  • Keamanan dengan prepared statements otomatis
  • Abstraksi dari dialek SQL spesifik
  • Kemampuan untuk membangun query secara dinamis
  • Integrasi dengan sistem caching

Memulai Query Builder

Untuk memulai menggunakan Query Builder, gunakan metode Storage() atau table():


// Menggunakan Storage() (rekomendasi)
$query = $this->Storage('users');

// Atau menggunakan table()
$model = new NexaModel();
$query = $model->table('users');
        

Setelah itu, Anda dapat merantai metode-metode lain untuk membangun query:


$users = $this->Storage('users')
              ->select('id, username, email')
              ->where('status', 'active')
              ->orderBy('created_at', 'DESC')
              ->limit(10)
              ->get();
        

Select Query

Select Dasar


// Select semua kolom
$users = $this->Storage('users')->get();

// Select kolom tertentu
$users = $this->Storage('users')
              ->select('id, username, email')
              ->get();

// Select dengan array
$users = $this->Storage('users')
              ->select(['id', 'username', 'email'])
              ->get();
        

Select dengan Alias


// Select dengan alias kolom
$users = $this->Storage('users')
              ->select('id, username, email AS user_email')
              ->get();
        

Select dengan Fungsi Agregasi


// Select dengan fungsi agregasi
$stats = $this->Storage('orders')
              ->select('COUNT(*) as total_orders, SUM(amount) as total_amount')
              ->get();
        

Where Conditions

Where Dasar


// Where dengan operator default (=)
$users = $this->Storage('users')
              ->where('status', 'active')
              ->get();

// Where dengan operator kustom
$users = $this->Storage('users')
              ->where('age', '>=', 18)
              ->get();

// Multiple where (AND)
$users = $this->Storage('users')
              ->where('status', 'active')
              ->where('age', '>=', 18)
              ->get();
        

Where dengan Array


// Where dengan array (semua kondisi AND)
$users = $this->Storage('users')
              ->where([
                  'status' => 'active',
                  'role' => 'admin'
              ])
              ->get();
        

OR Where


// OR Where
$users = $this->Storage('users')
              ->where('status', 'active')
              ->orWhere('status', 'pending')
              ->get();

// Kombinasi AND dan OR
$users = $this->Storage('users')
              ->where('status', 'active')
              ->where(function($query) {
                  $query->where('role', 'admin')
                        ->orWhere('role', 'editor');
              })
              ->get();
        

Where IN


// Where IN
$users = $this->Storage('users')
              ->whereIn('role', ['admin', 'editor', 'moderator'])
              ->get();

// Where NOT IN
$users = $this->Storage('users')
              ->whereNotIn('status', ['banned', 'deleted'])
              ->get();
        

Where NULL


// Where IS NULL
$users = $this->Storage('users')
              ->whereNull('deleted_at')
              ->get();

// Where IS NOT NULL
$users = $this->Storage('users')
              ->whereNotNull('email_verified_at')
              ->get();
        

Where BETWEEN


// Where BETWEEN
$users = $this->Storage('users')
              ->whereBetween('age', [18, 30])
              ->get();

// Where NOT BETWEEN
$users = $this->Storage('users')
              ->whereNotBetween('created_at', ['2023-01-01', '2023-01-31'])
              ->get();
        

Join Queries

Inner Join


// Inner Join
$usersWithOrders = $this->Storage('users')
                        ->join('orders', 'users.id', '=', 'orders.user_id')
                        ->select('users.*, orders.id as order_id, orders.amount')
                        ->get();
        

Left Join


// Left Join
$usersWithOrders = $this->Storage('users')
                        ->leftJoin('orders', 'users.id', '=', 'orders.user_id')
                        ->select('users.*, orders.id as order_id, orders.amount')
                        ->get();
        

Multiple Joins


// Multiple Joins
$usersWithOrdersAndProducts = $this->Storage('users')
                                   ->join('orders', 'users.id', '=', 'orders.user_id')
                                   ->join('order_items', 'orders.id', '=', 'order_items.order_id')
                                   ->join('products', 'order_items.product_id', '=', 'products.id')
                                   ->select('users.username, orders.id as order_id, products.name as product_name')
                                   ->get();
        

Ordering, Grouping, dan Limiting

Order By


// Order By sederhana
$users = $this->Storage('users')
              ->orderBy('created_at', 'DESC')
              ->get();

// Multiple Order By
$users = $this->Storage('users')
              ->orderBy('role')
              ->orderBy('created_at', 'DESC')
              ->get();
        

Group By dan Having


// Group By
$usersByRole = $this->Storage('users')
                   ->select('role, COUNT(*) as user_count')
                   ->groupBy('role')
                   ->get();

// Group By dengan Having
$popularRoles = $this->Storage('users')
                    ->select('role, COUNT(*) as user_count')
                    ->groupBy('role')
                    ->having('user_count', '>', 5)
                    ->get();
        

Limit dan Offset


// Limit
$users = $this->Storage('users')
              ->limit(10)
              ->get();

// Limit dan Offset
$users = $this->Storage('users')
              ->limit(10)
              ->offset(20)
              ->get();
        

Metode Agregasi

Count


// Count sederhana
$count = $this->Storage('users')->count();

// Count dengan kondisi
$activeCount = $this->Storage('users')
                   ->where('status', 'active')
                   ->count();
        

Sum, Avg, Min, Max


// Sum
$totalAmount = $this->Storage('orders')->sum('amount');

// Average
$avgAmount = $this->Storage('orders')->avg('amount');

// Min
$minAmount = $this->Storage('orders')->min('amount');

// Max
$maxAmount = $this->Storage('orders')->max('amount');
        

Agregasi Multiple Kolom


// Multiple agregasi dalam satu query
$stats = $this->Storage('orders')->countByColumn(['amount', 'tax', 'shipping'], 'sum');
// Returns: ['amount' => 15000, 'tax' => 750, 'shipping' => 500]

// Dengan persentase
$statsWithPercentage = $this->Storage('orders')->sumColumnsWithPercentage(['amount', 'tax', 'shipping']);
// Returns: ['amount' => 15000, 'tax' => 750, 'shipping' => 500, 'peramount' => '92.3%', 'pertax' => '4.6%', 'pershipping' => '3.1%']
        

Advanced Queries

Raw Queries


// Raw SQL query
$results = $this->Storage('users')->raw('SELECT * FROM users WHERE status = ? AND role = ?', ['active', 'admin']);
        

Subqueries


// Subquery dalam SELECT
$users = $this->Storage('users')
              ->select('users.*, (SELECT COUNT(*) FROM orders WHERE orders.user_id = users.id) as order_count')
              ->get();

// Subquery dalam WHERE
$activeUsers = $this->Storage('users')
                   ->whereIn('id', function($query) {
                       $query->select('user_id')
                             ->from('orders')
                             ->where('status', 'completed');
                   })
                   ->get();
        

Union


// Union query
$activeUsers = $this->Storage('users')->where('status', 'active');

$results = $this->Storage('archived_users')
               ->where('status', 'active')
               ->union($activeUsers)
               ->get();
        

Query Debugging

NexaModel menyediakan beberapa metode untuk debugging query:


// Mendapatkan SQL query string
$sql = $this->Storage('users')
            ->where('status', 'active')
            ->toSql();

// Mendapatkan binding values
$bindings = $this->Storage('users')
                ->where('status', 'active')
                ->getBindings();

// Dump query (print tanpa menghentikan eksekusi)
$this->Storage('users')
     ->where('status', 'active')
     ->dump()
     ->get();

// Debug query (print dan hentikan eksekusi)
$this->Storage('users')
     ->where('status', 'active')
     ->dd();
        

Query Caching

NexaModel menyediakan sistem caching untuk meningkatkan performa query:


// Query dengan cache (default)
$users = $this->Storage('users')
              ->where('status', 'active')
              ->get(); // Hasil akan di-cache

// Query tanpa cache
$users = $this->Storage('users')
              ->withoutCache()
              ->where('status', 'active')
              ->get(); // Hasil tidak di-cache

// Membersihkan cache
$this->Storage('users')->clearCache();

// Mendapatkan statistik cache
$cacheStats = $this->Storage('users')->getCacheStats();
        

Best Practices

  • Gunakan Query Builder untuk membangun query yang kompleks secara bertahap
  • Manfaatkan chaining method untuk membuat kode lebih ringkas dan mudah dibaca
  • Gunakan named parameters untuk meningkatkan kejelasan kode
  • Aktifkan caching untuk query yang sering dijalankan dan tidak sering berubah
  • Gunakan metode debugging untuk memverifikasi query yang dihasilkan
  • Batasi jumlah hasil dengan limit() untuk menghindari overload memori
  • Gunakan select() dengan kolom spesifik daripada mengambil semua kolom