XOOPS Pembuat Kueri
XOOPS Query Builder menyediakan antarmuka yang modern dan lancar untuk membuat kueri SQL. Ini membantu mencegah injeksi SQL, meningkatkan keterbacaan, dan menyediakan abstraksi database untuk beberapa sistem database.
Arsitektur Pembuat Kueri
Section titled “Arsitektur Pembuat Kueri”graph TD A[QueryBuilder] -->|builds| B[SELECT Queries] A -->|builds| C[INSERT Queries] A -->|builds| D[UPDATE Queries] A -->|builds| E[DELETE Queries]
F[Table] -->|chains| G[select] F -->|chains| H[where] F -->|chains| I[orderBy] F -->|chains| J[limit]
G -->|chains| K[join] G -->|chains| H H -->|chains| I I -->|chains| J
L[Execute Methods] -->|returns| M[Results] L -->|returns| N[Count] L -->|returns| O[First/Last]Kelas QueryBuilder
Section titled “Kelas QueryBuilder”Kelas pembuat kueri utama dengan antarmuka yang lancar.
Ikhtisar Kelas
Section titled “Ikhtisar Kelas”namespace Xoops\Database;
class QueryBuilder{ protected string $table = ''; protected string $type = 'SELECT'; protected array $selects = []; protected array $joins = []; protected array $wheres = []; protected array $orders = []; protected int $limit = 0; protected int $offset = 0; protected array $bindings = [];}Metode Statis
Section titled “Metode Statis”Membuat pembuat kueri baru untuk tabel.
public static function table(string $table): QueryBuilderParameter:
| Parameter | Ketik | Deskripsi |
|---|---|---|
$table | tali | Nama tabel (dengan atau tanpa awalan) |
Pengembalian: QueryBuilder - Contoh pembuat kueri
Contoh:
$query = QueryBuilder::table('users');$query = QueryBuilder::table('xoops_users'); // With prefixPILIH Kueri
Section titled “PILIH Kueri”Menentukan kolom yang akan dipilih.
public function select(...$columns): selfParameter:
| Parameter | Ketik | Deskripsi |
|---|---|---|
...$columns | susunan | Nama atau ekspresi kolom |
Pengembalian: self - Untuk rangkaian metode
Contoh:
// Simple selectQueryBuilder::table('users') ->select('id', 'username', 'email') ->get();
// Select with aliasesQueryBuilder::table('users') ->select('id as user_id', 'username as name') ->get();
// Select all columnsQueryBuilder::table('users') ->select('*') ->get();
// Select with expressionsQueryBuilder::table('orders') ->select('id', 'COUNT(*) as total_items') ->groupBy('id') ->get();dimana
Section titled “dimana”Menambahkan kondisi WHERE.
public function where(string $column, string $operator = '=', mixed $value = null): selfParameter:
| Parameter | Ketik | Deskripsi |
|---|---|---|
$column | tali | Nama kolom |
$operator | tali | Operator perbandingan |
$value | campuran | Nilai untuk membandingkan |
Pengembalian: self - Untuk rangkaian metode
Operator:
| Operator | Deskripsi | Contoh |
|---|---|---|
= | Sama | ->where('status', '=', 'active') |
!= atau <> | Tidak sama | ->where('status', '!=', 'deleted') |
> | Lebih besar dari | ->where('price', '>', 100) |
< | Kurang dari | ->where('price', '<', 100) |
>= | Lebih besar atau sama | ->where('age', '>=', 18) |
<= | Kurang atau sama | ->where('age', '<=', 65) |
LIKE | Pencocokan pola | ->where('name', 'LIKE', '%john%') |
IN | Dalam daftar | ->where('status', 'IN', ['active', 'pending']) |
NOT IN | Tidak ada dalam daftar | ->where('id', 'NOT IN', [1, 2, 3]) |
BETWEEN | Rentang | ->where('age', 'BETWEEN', [18, 65]) |
IS NULL | Apakah nol | ->where('deleted_at', 'IS NULL') |
IS NOT NULL | Bukan nol | ->where('deleted_at', 'IS NOT NULL') |
Contoh:
// Single conditionQueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->get();
// Multiple conditions (AND)QueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->where('age', '>=', 18) ->get();
// IN operatorQueryBuilder::table('products') ->select('*') ->where('category_id', 'IN', [1, 2, 3]) ->get();
// LIKE operatorQueryBuilder::table('users') ->select('*') ->where('email', 'LIKE', '%@example.com') ->get();
// NULL checkQueryBuilder::table('users') ->select('*') ->where('deleted_at', 'IS NULL') ->get();atau Dimana
Section titled “atau Dimana”Menambahkan kondisi OR.
public function orWhere(string $column, string $operator = '=', mixed $value = null): selfContoh:
QueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->orWhere('premium', '=', 1) ->get(); // SELECT * FROM users WHERE status = 'active' OR premium = 1di manaDi/di manaTidakDi
Section titled “di manaDi/di manaTidakDi”Metode kenyamanan untuk IN/NOT IN.
public function whereIn(string $column, array $values): selfpublic function whereNotIn(string $column, array $values): selfContoh:
QueryBuilder::table('posts') ->select('*') ->whereIn('status', ['published', 'scheduled']) ->get();
QueryBuilder::table('comments') ->select('*') ->whereNotIn('spam_score', [8, 9, 10]) ->get();di manaNull / di manaNotNull
Section titled “di manaNull / di manaNotNull”Metode kemudahan untuk pemeriksaan NULL.
public function whereNull(string $column): selfpublic function whereNotNull(string $column): selfContoh:
QueryBuilder::table('users') ->select('*') ->whereNotNull('verified_at') ->get();di mana Antara
Section titled “di mana Antara”Memeriksa apakah nilai berada di antara dua nilai.
public function whereBetween(string $column, array $values): selfContoh:
QueryBuilder::table('products') ->select('*') ->whereBetween('price', [10, 100]) ->get();
QueryBuilder::table('orders') ->select('*') ->whereBetween('created_at', ['2024-01-01', '2024-12-31']) ->get();bergabung
Section titled “bergabung”Menambahkan INNER JOIN.
public function join( string $table, string $first, string $operator = '=', string $second = null): selfContoh:
QueryBuilder::table('posts') ->select('posts.*', 'users.username', 'categories.name') ->join('users', 'posts.user_id', '=', 'users.id') ->join('categories', 'posts.category_id', '=', 'categories.id') ->where('posts.published', '=', 1) ->get();kiriGabung / kananGabung
Section titled “kiriGabung / kananGabung”Jenis gabungan alternatif.
public function leftJoin( string $table, string $first, string $operator = '=', string $second = null): self
public function rightJoin( string $table, string $first, string $operator = '=', string $second = null): selfContoh:
QueryBuilder::table('users') ->select('users.*', 'COUNT(posts.id) as post_count') ->leftJoin('posts', 'users.id', '=', 'posts.user_id') ->groupBy('users.id') ->get();grupOleh
Section titled “grupOleh”Kelompokkan hasil berdasarkan kolom.
public function groupBy(...$columns): selfContoh:
QueryBuilder::table('orders') ->select('user_id', 'COUNT(*) as order_count', 'SUM(total) as total_spent') ->groupBy('user_id') ->get();
QueryBuilder::table('sales') ->select('department', 'region', 'SUM(amount) as total') ->groupBy('department', 'region') ->get();memiliki
Section titled “memiliki”Menambahkan kondisi HAVING.
public function having(string $column, string $operator = '=', mixed $value = null): selfContoh:
QueryBuilder::table('orders') ->select('user_id', 'COUNT(*) as order_count') ->groupBy('user_id') ->having('order_count', '>', 5) ->get();dipesanOleh
Section titled “dipesanOleh”Hasil pesanan.
public function orderBy(string $column, string $direction = 'ASC'): selfParameter:
| Parameter | Ketik | Deskripsi |
|---|---|---|
$column | tali | Kolom untuk diurutkan berdasarkan |
$direction | tali | ASC atau DESC |
Contoh:
// Single orderQueryBuilder::table('users') ->select('*') ->orderBy('created_at', 'DESC') ->get();
// Multiple ordersQueryBuilder::table('posts') ->select('*') ->orderBy('category_id', 'ASC') ->orderBy('created_at', 'DESC') ->get();
// Random orderQueryBuilder::table('quotes') ->select('*') ->orderBy('RAND()') ->get();batas / offset
Section titled “batas / offset”Batasi dan offset hasil.
public function limit(int $limit): selfpublic function offset(int $offset): selfContoh:
// Simple limitQueryBuilder::table('posts') ->select('*') ->limit(10) ->get();
// Pagination$page = 2;$perPage = 20;$offset = ($page - 1) * $perPage;
QueryBuilder::table('posts') ->select('*') ->limit($perPage) ->offset($offset) ->get();Metode Eksekusi
Section titled “Metode Eksekusi”dapatkan
Section titled “dapatkan”Menjalankan kueri dan mengembalikan semua hasil.
public function get(): arrayPengembalian: array - Kumpulan baris hasil
Contoh:
$users = QueryBuilder::table('users') ->select('id', 'username', 'email') ->where('status', '=', 'active') ->orderBy('username') ->get();
foreach ($users as $user) { echo $user['username'] . ' (' . $user['email'] . ')' . "\n";}pertama
Section titled “pertama”Mendapatkan hasil pertama.
public function first(): ?arrayPengembalian: ?array - Baris pertama atau nol
Contoh:
$user = QueryBuilder::table('users') ->select('*') ->where('id', '=', 123) ->first();
if ($user) { echo 'Found: ' . $user['username'];}terakhir
Section titled “terakhir”Mendapatkan hasil terakhir.
public function last(): ?arrayContoh:
$latestPost = QueryBuilder::table('posts') ->select('*') ->orderBy('created_at', 'DESC') ->last();hitungan
Section titled “hitungan”Mendapat hitungan hasil.
public function count(): intPengembalian: int - Jumlah baris
Contoh:
$activeUsers = QueryBuilder::table('users') ->where('status', '=', 'active') ->count();
echo "Active users: $activeUsers";Memeriksa apakah kueri mengembalikan hasil apa pun.
public function exists(): boolPengembalian: bool - Benar jika ada hasilContoh:
if (QueryBuilder::table('users')->where('email', '=', 'test@example.com')->exists()) { echo 'User already exists';}agregat
Section titled “agregat”Mendapat nilai agregat.
public function aggregate(string $function, string $column): mixedContoh:
$maxPrice = QueryBuilder::table('products') ->aggregate('MAX', 'price');
$avgAge = QueryBuilder::table('users') ->aggregate('AVG', 'age');
$totalSales = QueryBuilder::table('orders') ->aggregate('SUM', 'total');MASUKKAN Kueri
Section titled “MASUKKAN Kueri”masukkan
Section titled “masukkan”Menyisipkan satu baris.
public function insert(array $values): boolContoh:
QueryBuilder::table('users')->insert([ 'username' => 'john', 'email' => 'john@example.com', 'password' => password_hash('secret', PASSWORD_BCRYPT), 'created_at' => date('Y-m-d H:i:s')]);masukkanBanyak
Section titled “masukkanBanyak”Menyisipkan beberapa baris.
public function insertMany(array $rows): boolContoh:
QueryBuilder::table('log_entries')->insertMany([ ['action' => 'login', 'user_id' => 1, 'timestamp' => time()], ['action' => 'logout', 'user_id' => 2, 'timestamp' => time()], ['action' => 'update', 'user_id' => 3, 'timestamp' => time()]]);PERBARUI Pertanyaan
Section titled “PERBARUI Pertanyaan”pembaruan
Section titled “pembaruan”Memperbarui baris.
public function update(array $values): intPengembalian: int - Jumlah baris yang terpengaruh
Contoh:
// Update single userQueryBuilder::table('users') ->where('id', '=', 123) ->update([ 'email' => 'newemail@example.com', 'updated_at' => date('Y-m-d H:i:s') ]);
// Update multiple rowsQueryBuilder::table('posts') ->where('status', '=', 'draft') ->where('created_at', '<', date('Y-m-d', strtotime('-30 days'))) ->update([ 'status' => 'archived' ]);kenaikan/penurunan
Section titled “kenaikan/penurunan”Menambah atau mengurangi kolom.
public function increment(string $column, int $amount = 1): intpublic function decrement(string $column, int $amount = 1): intContoh:
// Increment view countQueryBuilder::table('posts') ->where('id', '=', 123) ->increment('views');
// Decrement stockQueryBuilder::table('products') ->where('id', '=', 456) ->decrement('stock', 5);HAPUS Pertanyaan
Section titled “HAPUS Pertanyaan”Menghapus baris.
public function delete(): intPengembalian: int - Jumlah baris yang dihapus
Contoh:
// Delete single recordQueryBuilder::table('comments') ->where('id', '=', 789) ->delete();
// Delete multiple recordsQueryBuilder::table('log_entries') ->where('created_at', '<', date('Y-m-d', strtotime('-30 days'))) ->delete();terpotong
Section titled “terpotong”Menghapus semua baris dari tabel.
public function truncate(): boolContoh:
// Clear all sessionsQueryBuilder::table('sessions')->truncate();Fitur Lanjutan
Section titled “Fitur Lanjutan”Ekspresi Mentah
Section titled “Ekspresi Mentah”QueryBuilder::table('products') ->select('id', 'name', QueryBuilder::raw('price * quantity as total')) ->get();Subkueri
Section titled “Subkueri”$recentPostIds = QueryBuilder::table('posts') ->select('id') ->where('created_at', '>', date('Y-m-d', strtotime('-7 days'))) ->toSql();
$comments = QueryBuilder::table('comments') ->select('*') ->whereIn('post_id', $recentPostIds) ->get();Mendapatkan SQL
Section titled “Mendapatkan SQL”public function toSql(): stringContoh:
$sql = QueryBuilder::table('users') ->select('id', 'username') ->where('status', '=', 'active') ->toSql();
echo $sql;// SELECT id, username FROM xoops_users WHERE status = ?Contoh Lengkap
Section titled “Contoh Lengkap”Pilih Kompleks dengan Gabungan
Section titled “Pilih Kompleks dengan Gabungan”<?php/** * Get posts with author and category info */
$posts = QueryBuilder::table('posts') ->select( 'posts.id', 'posts.title', 'posts.content', 'posts.created_at', 'users.username as author', 'categories.name as category' ) ->join('users', 'posts.user_id', '=', 'users.id') ->join('categories', 'posts.category_id', '=', 'categories.id') ->where('posts.published', '=', 1) ->orderBy('posts.created_at', 'DESC') ->limit(10) ->get();
foreach ($posts as $post) { echo '<article>'; echo '<h2>' . htmlspecialchars($post['title']) . '</h2>'; echo '<p class="meta">By ' . htmlspecialchars($post['author']) . ' in ' . htmlspecialchars($post['category']) . '</p>'; echo '<p>' . htmlspecialchars($post['content']) . '</p>'; echo '</article>';}Paginasi dengan QueryBuilder
Section titled “Paginasi dengan QueryBuilder”<?php/** * Paginated results */
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;$perPage = 20;$offset = ($page - 1) * $perPage;
// Get total count$total = QueryBuilder::table('articles') ->where('status', '=', 'published') ->count();
// Get page results$articles = QueryBuilder::table('articles') ->select('*') ->where('status', '=', 'published') ->orderBy('created_at', 'DESC') ->limit($perPage) ->offset($offset) ->get();
// Calculate pagination$pages = ceil($total / $perPage);
// Display resultsforeach ($articles as $article) { echo '<div class="article">' . htmlspecialchars($article['title']) . '</div>';}
// Display pagination linksif ($pages > 1) { echo '<nav class="pagination">'; for ($i = 1; $i <= $pages; $i++) { if ($i == $page) { echo '<span class="current">' . $i . '</span>'; } else { echo '<a href="?page=' . $i . '">' . $i . '</a>'; } } echo '</nav>';}Analisis Data dengan Agregat
Section titled “Analisis Data dengan Agregat”<?php/** * Sales analysis */
// Total sales by region$regionSales = QueryBuilder::table('orders') ->select('region', QueryBuilder::raw('SUM(total) as total_sales'), QueryBuilder::raw('COUNT(*) as order_count')) ->groupBy('region') ->orderBy('total_sales', 'DESC') ->get();
foreach ($regionSales as $region) { echo $region['region'] . ': $' . number_format($region['total_sales'], 2) . ' (' . $region['order_count'] . ' orders)' . "\n";}
// Average order value$avgOrderValue = QueryBuilder::table('orders') ->aggregate('AVG', 'total');
echo 'Average order value: $' . number_format($avgOrderValue, 2);Praktik Terbaik
Section titled “Praktik Terbaik”- Gunakan Kueri Parameterisasi - QueryBuilder menangani pengikatan parameter secara otomatis
- Metode Rantai - Manfaatkan antarmuka yang lancar untuk kode yang dapat dibaca
- Uji Output SQL - Gunakan
toSql()untuk memverifikasi kueri yang dihasilkan - Gunakan Indeks - Pastikan kolom yang sering ditanyakan diindeks
- Batasi Hasil - Selalu gunakan
limit()untuk kumpulan data besar - Gunakan Agregat - Biarkan database melakukan counting/summing, bukan PHP
- Escape Output - Selalu keluar dari data yang ditampilkan dengan
htmlspecialchars() - Kinerja Indeks - Pantau kueri yang lambat dan optimalkan
Dokumentasi Terkait
Section titled “Dokumentasi Terkait”- XoopsDatabase - Lapisan database dan koneksi
- Kriteria - Sistem kueri berbasis Kriteria Warisan
- ../Core/XoopsObject - Persistensi objek data
- ../Module/Module-System - Operasi basis data module
Lihat juga: Basis Data XOOPS API