abdulelahragih/querybuilder
最新稳定版本:1.3.0
Composer 安装命令:
composer require abdulelahragih/querybuilder
包简介
Fast, lightweight and simple SQL query builder that does not depend on any third-party library besides PDO to execute the queries in a safe way. The syntax is inspired by Laravel Query Builder.
README 文档
README
Fast, lightweight, and simple SQL query builder that does not depend on any third-party library besides PDO to execute the queries in a safe way. The syntax is inspired by Laravel Query Builder.
Features
- Automatic parameter binding via an internal bindings manager.
- Comprehensive WHERE builder: nested groups,
IN/NOT IN,LIKE/NOT LIKE,NULL/NOT NULL,BETWEEN/NOT BETWEEN. - Rich JOINs:
INNER,LEFT,RIGHT, andFULL(only on dialects that support it, e.g., PostgreSQL) with nested conditions andonhelpers. - Pagination:
paginate(length-aware) andsimplePaginate(no total count) with page name support. - Dialect-aware SQL generation with automatic detection (MySQL & Postgres for now).
- Inserts, updates, deletes with safety checks (no UPDATE/DELETE without WHERE).
- Upserts with dialect-specific behavior.
- Convenience helpers:
first,pluck,distinct,orderBy,limit,offset,rawexpressions,objectConverter. - Results as a fluent
Collectionand paginator objects.
Installation
Install via Composer:
composer require abdulelahragih/querybuilder
Getting Started
Create a builder from a PDO instance. Dialect is auto-detected from PDO::ATTR_DRIVER_NAME (pgsql → Postgres; otherwise MySQL):
use Abdulelahragih\QueryBuilder\QueryBuilder; $pdo = /* your PDO connection */; $qb = new QueryBuilder($pdo); $rows = $qb->table('users') ->select('id', 'username', 'phone_number', 'gender') ->where('role_id', '=', 1) ->join('images', 'images.user_id', '=', 'users.id') ->orderBy('id', 'DESC') ->limit(10) ->get(); // returns Collection
You can also use the thin DB wrapper (instance-based) or the DBSingleton for a static facade if you prefer:
use Abdulelahragih\QueryBuilder\DB; use Abdulelahragih\QueryBuilder\DBSingleton; // Instance wrapper $db = new DB($pdo); $users = $db->table('users')->select('id')->get(); // Static facade DBSingleton::init($pdo); $firstId = DBSingleton::table('users')->first('id');
Pagination
Length-aware pagination returns totals and page info:
$p = $qb->table('users') ->orderBy('id', 'DESC') ->paginate($page, $perPage, pageName: 'page'); // $p is LengthAwarePaginator (items + total, pages, prev/next)
Simple pagination is lighter weight:
$p = $qb->table('users')->simplePaginate($page, $perPage); // $p is SimplePaginator (items + prev/next)
Inserts and Upserts
- Insert single or multiple rows:
$qb->table('users')->insert(['id' => 100, 'name' => 'John']); $qb->table('users')->insert([ ['id' => 100, 'name' => 'John'], ['id' => 101, 'name' => 'Jane'], ]);
- Upsert with a unified API across dialects:
use Abdulelahragih\QueryBuilder\Grammar\Expression; // Update non-unique columns automatically when conflicts occur $qb->table('users')->upsert( ['id' => 100, 'name' => 'John', 'age' => 26], uniqueBy: ['id'], ); // Explicit assignments (MySQL uses VALUES(), Postgres uses EXCLUDED) $qb->table('users')->upsert( ['id' => 100, 'name' => 'John', 'age' => 26], uniqueBy: ['id'], updateOnDuplicate: [ 'name', // infer from column name 'updated_at' => Expression::make('NOW()'), // raw expression ], );
- Do-nothing on conflict (Postgres):
$qb->table('users')->insertOrIgnore(['id' => 100, 'name' => 'John'], uniqueColumns: ['id']);
- Insert and get the generated id (Postgres supports RETURNING, MySQL uses lastInsertId):
$id = $qb->table('users')->insertGetId(['name' => 'John']); // Optionally specify id column name $id = $qb->table('users')->insertGetId(['name' => 'Jane'], 'user_id');
Updates and Deletes
Both operations require a WHERE clause for safety and return the affected rows count:
$updated = $qb->table('users')->where('id', '=', 1)->update(['name' => 'Sam']); $deleted = $qb->table('users')->whereIn('id', [1, 2])->delete();
WHERE and JOIN Builders
- WHERE helpers:
where,orWhere,whereIn,whereNotIn,whereLike,whereNotLike,whereNull,whereNotNull,whereBetween,whereNotBetween, nested closures. - JOIN helpers:
join,leftJoin,rightJoin,fullJoin, plus nestedwhere/orWhereinside join closures andon/orOnfor column comparisons.
Examples (WHERE):
// Basic where and multiple conditions (AND) $qb->table('users') ->where('role_id', '=', 1) ->where('status', '=', 'active') ->toSql(); // OR conditions $qb->table('users') ->where('role_id', '=', 1) ->orWhere('role_id', '=', 2) ->toSql(); // Nested groups $qb->table('users') ->where('id', '=', 1) ->orWhere(function ($w) { $w->where('id', '=', 2) ->where(function ($inner) { $inner->where('name', '=', 'Sam') ->orWhere('name', '=', 'John'); }); }) ->toSql(); // IN / NOT IN $qb->table('users') ->whereIn('id', [1, 2, 3]) ->whereNotIn('status', ['banned']) ->toSql(); // LIKE / NOT LIKE $qb->table('users') ->whereLike('name', '%Sam%') ->whereNotLike('email', '%@spam.com') ->toSql(); // NULL / NOT NULL $qb->table('users') ->whereNull('deleted_at') ->whereNotNull('email') ->toSql(); // BETWEEN / NOT BETWEEN $qb->table('orders') ->whereBetween('amount', 10, 100) ->whereNotBetween('discount', 20, 30) ->toSql();
Examples (JOIN):
// Simple inner join with column-to-column comparison $qb->table('users') ->join('images', 'images.user_id', '=', 'users.id') ->toSql(); // LEFT / RIGHT / FULL joins $qb->table('users') ->leftJoin('orders', 'orders.user_id', '=', 'users.id') ->rightJoin('profiles', 'profiles.user_id', '=', 'users.id') ->toSql(); // Join with additional filters and nested groups $qb->table('users') ->join('images', function ($j) { $j->on('images.user_id', '=', 'users.id'); $j->orWhere('images.user_id', '=', 1); $j->where(function ($nested) { $nested->where('images.user_id', '=', 3); $nested->orWhere('images.id', '=', 1); }); }) ->toSql(); // Using orOn for alternative column matches $qb->table('users') ->join('orders', function ($j) { $j->on('orders.user_id', '=', 'users.id') ->orOn('orders.alt_user_id', '=', 'users.id'); }) ->toSql(); // Multiple joins chained $qb->table('users u') ->join('orders o', 'o.user_id', '=', 'u.id') ->join('comments c', 'c.user_id', '=', 'u.id') ->select('u.id', 'o.amount') ->toSql();
Object Conversion
Map rows to custom objects after fetching:
$users = $qb->table('users') ->objectConverter(fn(array $row) => (object) $row) ->get();
Transactions (Using the DB Wrapper)
Let the builder handle transactions:
use Abdulelahragih\QueryBuilder\DB; $db = new DB($pdo); $db->transaction(function () use ($db) { $db->table('users')->insert(['id' => 200, 'name' => 'Txn']); });
Or manually:
use Abdulelahragih\QueryBuilder\DB; $db = new DB($pdo); $db->beginTransaction(); try { $db->table('users')->insert(['id' => 200, 'name' => 'Txn']); $db->commit(); } catch (Exception $e) { $db->rollBack(); }
Notes
- Update/Delete without a WHERE clause throws an exception by default.
insertGetIdexpects a single row payload.- Feature set varies slightly by dialect (e.g., Postgres
RETURNING,ON CONFLICT ... DO NOTHING).
Contribution
Contributions are welcome!
统计信息
- 总下载量: 1.65k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 8
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: GPL-3.0-only
- 更新时间: 2023-09-01