Database Query Builder
Fluent SQL query builder backed by DatabaseDriverInterface identifier protection and value bindings.
Purpose
QueryBuilder builds SQL for common reads and writes while delegating execution and identifier protection to DatabaseDriverInterface. Create it through Database::table() or QueryBuilder::make($driver)->table($table).
Selecting rows
Use table(), select(), distinct(), where(), orderBy(), groupBy(), having(), limit(), offset() and getArray() for typical read queries. get() returns DatabaseResultInterface or false; getArray() returns an array of associative rows.
$rows = $db->table('articles')
->select(['id', 'title', 'created_at'])
->where('published', 1)
->whereLike('title', 'framework')
->orderBy('created_at', 'DESC')
->limit(20)
->getArray();
Single values
first() returns one associative row or null. value() returns one selected column from the first row. pluck() returns a list of values or an associative array when a key column is supplied. exists() and doesntExist() check presence efficiently.
$article = $db->table('articles')->where('id', $id)->first();
$title = $db->table('articles')->where('id', $id)->value('title');
$ids = $db->table('articles')->where('published', 1)->pluck('id');
Conditions
Condition helpers include where(), orWhere(), whereLike(), whereNotLike(), whereIn(), whereNotIn(), whereNull(), whereNotNull(), whereBetween(), whereNotBetween(), subquery variants, raw variants and matching having* methods. Array where payloads are treated as equality conditions.
Joins and subqueries
join() accepts a table and explicit join condition. joinSubquery(), leftJoinSubquery(), selectSubquery() and fromSubquery() compose nested QueryBuilder instances with merged bindings.
$rows = $db->table('articles AS a')
->select(['a.id', 'a.title'])
->join('users AS u', 'u.id = a.author_id', 'LEFT')
->where('a.published', 1)
->getArray();
Writes
Write helpers include insert(), batchInsert(), insertOrIgnore(), upsert(), update(), batchUpdate(), delete(), increment() and decrement(). update(), delete(), increment() and decrement() return false when no WHERE condition is present to avoid accidental table-wide writes.
$db->table('articles')->insert([
'title' => 'Hello',
'published' => 1,
]);
$db->table('articles')
->where('id', $id)
->update(['title' => 'Updated']);
Streaming and chunks
cursor() yields rows from the driver cursor. For model-level chunking use Model::chunk(); QueryBuilder itself exposes limit/offset and cursor primitives.
Locks and portability
lockForUpdate() appends FOR UPDATE and sharedLock() appends LOCK IN SHARE MODE. These lock clauses are MySQL-oriented and may not be portable to every ODBC or PDO target.
Safety
Normal table and column APIs accept identifiers and protect them. Raw SQL APIs such as selectRaw(), whereRaw(), havingRaw() and fromRaw() are explicit escape hatches. Do not concatenate user input into raw SQL; pass values through bindings.