XOOPS Query Builder
Der XOOPS Query Builder bietet eine moderne, fließende Schnittstelle zum Erstellen von SQL-Abfragen. Er hilft, SQL-Injection zu verhindern, verbessert die Lesbarkeit und bietet Datenbankabstraktion für mehrere Datenbanksysteme.
Query Builder Architektur
Abschnitt betitelt „Query Builder Architektur“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]QueryBuilder Klasse
Abschnitt betitelt „QueryBuilder Klasse“Die Haupt-QueryBuilder-Klasse mit fließender Schnittstelle.
Klassenübersicht
Abschnitt betitelt „Klassenübersicht“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 = [];}Statische Methoden
Abschnitt betitelt „Statische Methoden“Erstellt einen neuen QueryBuilder für eine Tabelle.
public static function table(string $table): QueryBuilderParameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
$table | string | Tabellenname (mit oder ohne Präfix) |
Rückgabewert: QueryBuilder - QueryBuilder-Instanz
Beispiel:
$query = QueryBuilder::table('users');$query = QueryBuilder::table('xoops_users'); // Mit PräfixSELECT Abfragen
Abschnitt betitelt „SELECT Abfragen“Gibt Spalten an, die ausgewählt werden sollen.
public function select(...$columns): selfParameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
...$columns | array | Spaltennamen oder Ausdrücke |
Rückgabewert: self - Für Methodenverkettung
Beispiel:
// Einfache AuswahlQueryBuilder::table('users') ->select('id', 'username', 'email') ->get();
// Auswahl mit AliasenQueryBuilder::table('users') ->select('id as user_id', 'username as name') ->get();
// Alle Spalten auswählenQueryBuilder::table('users') ->select('*') ->get();
// Auswahl mit AusdrückenQueryBuilder::table('orders') ->select('id', 'COUNT(*) as total_items') ->groupBy('id') ->get();Fügt eine WHERE-Bedingung hinzu.
public function where(string $column, string $operator = '=', mixed $value = null): selfParameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
$column | string | Spaltenname |
$operator | string | Vergleichsoperator |
$value | mixed | Zu vergleichender Wert |
Rückgabewert: self - Für Methodenverkettung
Operatoren:
| Operator | Beschreibung | Beispiel |
|---|---|---|
= | Gleich | ->where('status', '=', 'active') |
!= oder <> | Nicht gleich | ->where('status', '!=', 'deleted') |
> | Größer als | ->where('price', '>', 100) |
< | Kleiner als | ->where('price', '<', 100) |
>= | Größer oder gleich | ->where('age', '>=', 18) |
<= | Kleiner oder gleich | ->where('age', '<=', 65) |
LIKE | Mustererkennung | ->where('name', 'LIKE', '%john%') |
IN | In Liste | ->where('status', 'IN', ['active', 'pending']) |
NOT IN | Nicht in Liste | ->where('id', 'NOT IN', [1, 2, 3]) |
BETWEEN | Bereich | ->where('age', 'BETWEEN', [18, 65]) |
IS NULL | Ist null | ->where('deleted_at', 'IS NULL') |
IS NOT NULL | Ist nicht null | ->where('deleted_at', 'IS NOT NULL') |
Beispiel:
// Einfache BedingungQueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->get();
// Mehrere Bedingungen (UND)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-ÜberprüfungQueryBuilder::table('users') ->select('*') ->where('deleted_at', 'IS NULL') ->get();orWhere
Abschnitt betitelt „orWhere“Fügt eine ODER-Bedingung hinzu.
public function orWhere(string $column, string $operator = '=', mixed $value = null): selfBeispiel:
QueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->orWhere('premium', '=', 1) ->get(); // SELECT * FROM users WHERE status = 'active' OR premium = 1whereIn / whereNotIn
Abschnitt betitelt „whereIn / whereNotIn“Komfortable Methoden für IN/NOT IN.
public function whereIn(string $column, array $values): selfpublic function whereNotIn(string $column, array $values): selfBeispiel:
QueryBuilder::table('posts') ->select('*') ->whereIn('status', ['published', 'scheduled']) ->get();
QueryBuilder::table('comments') ->select('*') ->whereNotIn('spam_score', [8, 9, 10]) ->get();whereNull / whereNotNull
Abschnitt betitelt „whereNull / whereNotNull“Komfortable Methoden für NULL-Überprüfungen.
public function whereNull(string $column): selfpublic function whereNotNull(string $column): selfBeispiel:
QueryBuilder::table('users') ->select('*') ->whereNotNull('verified_at') ->get();whereBetween
Abschnitt betitelt „whereBetween“Überprüft, ob Wert zwischen zwei Werten liegt.
public function whereBetween(string $column, array $values): selfBeispiel:
QueryBuilder::table('products') ->select('*') ->whereBetween('price', [10, 100]) ->get();
QueryBuilder::table('orders') ->select('*') ->whereBetween('created_at', ['2024-01-01', '2024-12-31']) ->get();Fügt einen INNER JOIN hinzu.
public function join( string $table, string $first, string $operator = '=', string $second = null): selfBeispiel:
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();leftJoin / rightJoin
Abschnitt betitelt „leftJoin / rightJoin“Alternative JOIN-Typen.
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): selfBeispiel:
QueryBuilder::table('users') ->select('users.*', 'COUNT(posts.id) as post_count') ->leftJoin('posts', 'users.id', '=', 'posts.user_id') ->groupBy('users.id') ->get();groupBy
Abschnitt betitelt „groupBy“Gruppiert Ergebnisse nach Spalte(n).
public function groupBy(...$columns): selfBeispiel:
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();Fügt eine HAVING-Bedingung hinzu.
public function having(string $column, string $operator = '=', mixed $value = null): selfBeispiel:
QueryBuilder::table('orders') ->select('user_id', 'COUNT(*) as order_count') ->groupBy('user_id') ->having('order_count', '>', 5) ->get();orderBy
Abschnitt betitelt „orderBy“Sortiert Ergebnisse.
public function orderBy(string $column, string $direction = 'ASC'): selfParameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
$column | string | Spalte zum Sortieren |
$direction | string | ASC oder DESC |
Beispiel:
// Einfache SortierungQueryBuilder::table('users') ->select('*') ->orderBy('created_at', 'DESC') ->get();
// Mehrfache SortierungenQueryBuilder::table('posts') ->select('*') ->orderBy('category_id', 'ASC') ->orderBy('created_at', 'DESC') ->get();
// Zufällige SortierungQueryBuilder::table('quotes') ->select('*') ->orderBy('RAND()') ->get();limit / offset
Abschnitt betitelt „limit / offset“Begrenzt und versetzt Ergebnisse.
public function limit(int $limit): selfpublic function offset(int $offset): selfBeispiel:
// Einfache BegrenzungQueryBuilder::table('posts') ->select('*') ->limit(10) ->get();
// Paginierung$page = 2;$perPage = 20;$offset = ($page - 1) * $perPage;
QueryBuilder::table('posts') ->select('*') ->limit($perPage) ->offset($offset) ->get();Ausführungs-Methoden
Abschnitt betitelt „Ausführungs-Methoden“Führt Abfrage aus und gibt alle Ergebnisse zurück.
public function get(): arrayRückgabewert: array - Array von Ergebniszeilen
Beispiel:
$users = QueryBuilder::table('users') ->select('id', 'username', 'email') ->where('status', '=', 'active') ->orderBy('username') ->get();
foreach ($users as $user) { echo $user['username'] . ' (' . $user['email'] . ')' . "\n";}Holt das erste Ergebnis.
public function first(): ?arrayRückgabewert: ?array - Erste Zeile oder null
Beispiel:
$user = QueryBuilder::table('users') ->select('*') ->where('id', '=', 123) ->first();
if ($user) { echo 'Found: ' . $user['username'];}Holt das letzte Ergebnis.
public function last(): ?arrayBeispiel:
$latestPost = QueryBuilder::table('posts') ->select('*') ->orderBy('created_at', 'DESC') ->last();Holt die Anzahl der Ergebnisse.
public function count(): intRückgabewert: int - Anzahl der Zeilen
Beispiel:
$activeUsers = QueryBuilder::table('users') ->where('status', '=', 'active') ->count();
echo "Active users: $activeUsers";Überprüft, ob Abfrage Ergebnisse zurückgibt.
public function exists(): boolRückgabewert: bool - True wenn Ergebnisse existieren
Beispiel:
if (QueryBuilder::table('users')->where('email', '=', 'test@example.com')->exists()) { echo 'User already exists';}aggregate
Abschnitt betitelt „aggregate“Holt Aggregatwerte.
public function aggregate(string $function, string $column): mixedBeispiel:
$maxPrice = QueryBuilder::table('products') ->aggregate('MAX', 'price');
$avgAge = QueryBuilder::table('users') ->aggregate('AVG', 'age');
$totalSales = QueryBuilder::table('orders') ->aggregate('SUM', 'total');INSERT Abfragen
Abschnitt betitelt „INSERT Abfragen“Fügt eine Zeile ein.
public function insert(array $values): boolBeispiel:
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')]);insertMany
Abschnitt betitelt „insertMany“Fügt mehrere Zeilen ein.
public function insertMany(array $rows): boolBeispiel:
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()]]);UPDATE Abfragen
Abschnitt betitelt „UPDATE Abfragen“Aktualisiert Zeilen.
public function update(array $values): intRückgabewert: int - Anzahl der betroffenen Zeilen
Beispiel:
// Einzelnen Benutzer aktualisierenQueryBuilder::table('users') ->where('id', '=', 123) ->update([ 'email' => 'newemail@example.com', 'updated_at' => date('Y-m-d H:i:s') ]);
// Mehrere Zeilen aktualisierenQueryBuilder::table('posts') ->where('status', '=', 'draft') ->where('created_at', '<', date('Y-m-d', strtotime('-30 days'))) ->update([ 'status' => 'archived' ]);increment / decrement
Abschnitt betitelt „increment / decrement“Erhöht oder vermindert eine Spalte.
public function increment(string $column, int $amount = 1): intpublic function decrement(string $column, int $amount = 1): intBeispiel:
// Aufrufscount erhöhenQueryBuilder::table('posts') ->where('id', '=', 123) ->increment('views');
// Lagerbestand verringernQueryBuilder::table('products') ->where('id', '=', 456) ->decrement('stock', 5);DELETE Abfragen
Abschnitt betitelt „DELETE Abfragen“Löscht Zeilen.
public function delete(): intRückgabewert: int - Anzahl der gelöschten Zeilen
Beispiel:
// Einzelnen Datensatz löschenQueryBuilder::table('comments') ->where('id', '=', 789) ->delete();
// Mehrere Datensätze löschenQueryBuilder::table('log_entries') ->where('created_at', '<', date('Y-m-d', strtotime('-30 days'))) ->delete();truncate
Abschnitt betitelt „truncate“Löscht alle Zeilen aus der Tabelle.
public function truncate(): boolBeispiel:
// Alle Sessions leerenQueryBuilder::table('sessions')->truncate();Erweiterte Funktionen
Abschnitt betitelt „Erweiterte Funktionen“Raw Expressions
Abschnitt betitelt „Raw Expressions“QueryBuilder::table('products') ->select('id', 'name', QueryBuilder::raw('price * quantity as total')) ->get();Subqueries
Abschnitt betitelt „Subqueries“$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();SQL erhalten
Abschnitt betitelt „SQL erhalten“public function toSql(): stringBeispiel:
$sql = QueryBuilder::table('users') ->select('id', 'username') ->where('status', '=', 'active') ->toSql();
echo $sql;// SELECT id, username FROM xoops_users WHERE status = ?Best Practices
Abschnitt betitelt „Best Practices“- Verwenden Sie parametrisierte Abfragen - QueryBuilder handhabt Parameter Binding automatisch
- Verketten Sie Methoden - Nutzen Sie die fließende Schnittstelle für lesbaren Code
- Testen Sie SQL-Ausgabe - Verwenden Sie
toSql(), um generierte Abfragen zu überprüfen - Verwenden Sie Indizes - Stellen Sie sicher, dass häufig abgefragte Spalten indexiert sind
- Begrenzen Sie Ergebnisse - Verwenden Sie immer
limit()für große Datenmengen - Nutzen Sie Aggregate - Lassen Sie die Datenbank zählen/summieren statt PHP
- Escape-Ausgabe - Escapen Sie immer angezeigte Daten mit
htmlspecialchars() - Indexleistung überwachen - Überwachen Sie langsame Abfragen und optimieren Sie entsprechend
Zugehörige Dokumentation
Abschnitt betitelt „Zugehörige Dokumentation“- XoopsDatabase - Datenbankschicht und Verbindungen
- Criteria - Älteres Criteria-basiertes Abfragesystem
- ../Core/XoopsObject - Datenpersistenz von Objekten
- ../Module/Module-System - Modul-Datenbankoperationen
Siehe auch: XOOPS Database API