mehedimi / wp-query-builder
WordPress 数据查询构建器
Requires
- php: >=5.6
- ext-mysqli: *
Requires (Dev)
- fakerphp/faker: ^1.20
- laravel/pint: ^1.15
- mockery/mockery: ^1.5
- phpstan/phpstan: ^1.9
- phpstan/phpstan-mockery: ^1.1
- phpunit/phpunit: ^9.5
- symfony/var-dumper: ^5.4
- vlucas/phpdotenv: ^5.4
README
WP Query Builder
WP Query Builder 是为开发者准备的包,可以简化 WordPress 中的查询编写体验。
安装
composer require mehedimi/wp-query-builder
如果您需要 WP Query Builder 的额外功能,则可以安装 WP Query Builder 扩展 包。
composer require mehedimi/wp-query-builder-ext
然后将 composer 的自动加载文件要求到您的主题或插件文件中。
运行 SQL 查询
DB 类提供了针对每种查询类型的方法:select、insert、update、delete、statement 和 affectingStatement。
运行 SELECT 查询
要运行基本的 SELECT 查询,您可以在 DB 类上使用 select 方法。
$users = DB::select('select * from users where active = ?', [1]);
运行 INSERT 语句
要执行 insert 语句,您可以在 DB 类上使用 insert 方法。与 select 类似,此方法接受 SQL 查询作为其第一个参数,并将绑定作为其第二个参数。
DB::insert('insert into users (id, name) values (?, ?)', [1, 'Username']);
运行 UPDATE 语句
$affected = DB::update( 'update users set votes = 100 where name = ?', ['Omar'] );
运行 DELETE 语句
$deleted = DB::delete('delete from users');
运行数据库查询
从表中检索所有行
您可以使用 DB 类提供的 table 方法开始查询。该 table 方法返回给定表的流畅查询构建器实例,允许您将更多约束附加到查询上,然后最终使用 get 方法检索查询的结果。
DB::table('posts')->get();
检索单行
如果您只需要从数据库表检索一行,您可以使用 DB 类的 first 方法。此方法将返回一个单独的 stdClass 对象。
$user = DB::table('users')->where('name', 'John')->first(); return $user->email;
聚合
查询构建器还提供了一系列方法来检索聚合值,如 count、max、min、avg 和 sum。您可以在构建查询后调用这些方法中的任何一个。
$users = DB::table('users')->count(); $price = DB::table('orders')->max('price');
当然,您可以将这些方法与其他子句结合使用,以微调聚合值的计算方式。
$price = DB::table('orders') ->where('finalized', 1) ->avg('price');
指定 SELECT 子句
您并不总是想从数据库表中选择所有列。使用 select 方法,您可以指定查询的定制 "select" 子句。
$users = DB::table('users') ->select('name', 'email') ->get();
distinct 方法允许您强制查询返回唯一结果。
$users = DB::table('users')->distinct()->get();
连接
内部连接子句
查询构建器还可以用于向查询中添加连接子句。要执行基本 "inner join",您可以在查询构建器实例上使用 join 方法。传递给 join 方法的第一个参数是需要连接的表的名称,其余参数指定连接的列约束。您甚至可以在单个查询中连接多个表。
<?php $users = DB::table('users') ->join('contacts', 'users.id', '=', 'contacts.user_id') ->join('orders', 'users.id', '=', 'orders.user_id') ->select('users.*', 'contacts.phone', 'orders.price') ->get();
左连接 / 右连接子句
如果您想执行 "left join" 或 "right join" 而不是 "inner join",请使用 leftJoin 或 rightJoin 方法。这些方法与 join 方法具有相同的签名。
<?php $users = DB::table('users') ->leftJoin('posts', 'users.id', '=', 'posts.user_id') ->get(); $users = DB::table('users') ->rightJoin('posts', 'users.id', '=', 'posts.user_id') ->get();
高级连接子句
您还可以指定更高级的连接子句。要开始,请将闭包作为第二个参数传递给 join 方法。闭包将接收一个 Mehedi\WPQueryBuilder\Query\Join 实例,允许您在 "连接" 子句上指定约束
<?php DB::table('users') ->join('contacts', function ($join) { $join->on('users.id', '=', 'contacts.user_id')->orOn(/* ... */); }) ->get();
如果您想在连接中使用 "where" 子句,可以使用 Join 实例提供的 where 和 orWhere 方法。与比较两个列不同,这些方法将列与一个值进行比较
DB::table('users') ->join('contacts', function ($join) { $join->on('users.id', '=', 'contacts.user_id') ->where('contacts.user_id', '>', 5); }) ->get();
基本 WHERE 子句
WHERE 子句
您可以使用查询构建器的 where 方法向查询添加 "where" 子句。调用 where 方法的最基本方式需要三个参数。第一个参数是列名。第二个参数是一个运算符,可以是数据库支持的任何运算符。第三个参数是要与列值比较的值。
例如,以下查询检索了 votes 列值为 100 且 age 列值大于 35 的用户
$users = DB::table('users') ->where('votes', '=', 100) ->where('age', '>', 35) ->get();
为了方便起见,如果您想验证列是否等于给定值,可以将值作为 where 方法的第二个参数传递。Laravel 将假设您想使用 = 运算符
$users = DB::table('users')->where('votes', 100)->get();
如前所述,您可以使用数据库系统支持的任何运算符
$users = DB::table('users') ->where('votes', '>=', 100) ->get(); $users = DB::table('users') ->where('votes', '<>', 100) ->get(); $users = DB::table('users') ->where('name', 'like', 'T%') ->get();
或 Where 子句
当链式调用查询构建器的 where 方法时,"where" 子句将使用 and 运算符连接起来。但是,您可以使用 orWhere 方法使用 or 运算符将子句连接到查询中。orWhere 方法接受与 where 方法相同的参数
$users = DB::table('users') ->where('votes', '>', 100) ->orWhere('name', 'John') ->get();
Where 嵌套
如果您需要在括号内分组 where 条件,可以使用 whereNested 方法
$users = DB::table('users') ->where('votes', '>', 100) ->whereNested(function($query) { $query->where('name', 'Some Name') ->where('votes', '>', 50); }, 'or') ->get();
上面的示例将生成以下 SQL
select * from users where votes > 100 or (name = 'Some Name' and votes > 50)
附加 WHERE 子句
whereBetween
whereBetween 方法验证列值是否介于两个值之间
$users = DB::table('users') ->whereBetween('votes', [1, 100]) ->get(); // For or query $users = DB::table('users') ->whereBetween('votes', [1, 100], 'or') ->get();
whereNotBetween
whereNotBetween 方法验证列值是否不在两个值之间
$users = DB::table('users') ->whereNotBetween('votes', [1, 100]) ->get(); // For or where $users = DB::table('users') ->whereNotBetween('votes', [1, 100], 'or') ->get();
whereIn / whereNotIn
whereIn 方法验证给定列的值是否包含在给定的数组中
$users = DB::table('users') ->whereIn('id', [1, 2, 3]) ->get(); // For or query $users = DB::table('users') ->whereIn('id', [1, 2, 3], 'or') ->get();
whereNotIn 方法验证给定列的值是否不包含在给定的数组中
$users = DB::table('users') ->whereNotIn('id', [1, 2, 3]) ->get(); // For or query $users = DB::table('users') ->whereNotIn('id', [1, 2, 3], 'or') ->get();
whereNull / whereNotNull
whereNull 方法验证给定列的值是 NULL
$users = DB::table('users') ->whereNull('updated_at') ->get();
whereNotNull 方法验证列的值不是 NULL
$users = DB::table('users') ->whereNotNull('updated_at') ->get();
whereColumn / orWhereColumn
whereColumn 方法可以用来验证两个列是否相等
$users = DB::table('users') ->whereColumn('first_name', 'last_name') ->get(); // For or query $users = DB::table('users') ->whereColumn('first_name', 'last_name', 'or') ->get();
您还可以向 whereColumn 方法传递一个比较运算符
$users = DB::table('users') ->whereColumn('updated_at', '>', 'created_at') ->get();
排序、分组、限制和偏移
排序
orderBy 方法
orderBy 方法允许您根据给定的列对查询结果进行排序。orderBy 方法接受的第一个参数应该是您希望排序的列,而第二个参数确定排序的方向,可以是 asc 或 desc
$users = DB::table('users') ->orderBy('name', 'desc') ->get();
要按多个列排序,您只需多次调用 orderBy
$users = DB::table('users') ->orderBy('name', 'desc') ->orderBy('email', 'asc') ->get();
分组
groupBy 方法
正如您所预期的,groupBy 方法可以用来对查询结果进行分组
$users = DB::table('users') ->groupBy('account_id') ->get();
限制和偏移
您可以使用 offset 和 limit 方法限制查询返回的结果数量,或跳过查询中给定数量的结果
$users = DB::table('users') ->offset(10) ->limit(5) ->get();
数据库事务
您可以使用DB类提供的transaction方法在数据库事务中运行一组操作。如果在事务闭包中抛出异常,事务将自动回滚。如果闭包执行成功,事务将自动提交。使用transaction方法时,您无需担心手动回滚或提交。
DB::transaction(function () { DB::table('posts')->where('ID', 2)->update(['title' => 'new title']); DB::table('posts')->where('ID', 4)->delete(); });
手动使用事务
如果您想手动开始事务并完全控制回滚和提交,可以使用DB外观类提供的beginTransaction方法。
DB::beginTransaction();
您可以通过rollback方法回滚事务。
DB::rollback();
最后,您可以通过commit方法提交事务。
DB::commit();
注意
所有这四个方法都支持与mysqli相同的$flags和$name参数,如下所示:
DB::beginTransaction(MYSQLI_TRANS_START_READ_WRITE, 'some-random-name'); DB::commit(MYSQLI_TRANS_START_READ_WRITE, 'some-random-name'); DB::rollback(MYSQLI_TRANS_START_READ_WRITE, 'some-random-name'); DB::transaction(function () { // Do something }, MYSQLI_TRANS_START_READ_WRITE, 'some-random-name');
定义关系
您可以在查询时定义您的关联。
一对一
一对一关系是数据库关系的一种基本类型。例如,一篇post可能关联一个名为color的postmeta。为了定义这种关系,我们只需在查询构建器上调用withOne方法。
DB::table('posts')->withOne('color', function(WithOne $relation){ $relation->from('postmeta'); }, 'post_id', 'ID')->get();
这将返回所有带有颜色的帖子。假设您有两个帖子,每个帖子都有一行postmeta。那么查询的输出将如下所示:
[
[
'ID' => 1,
'post_title' => 'Post 1'
'color' => [
'post_id' => 1,
'name' => 'color',
'value' => 'red'
]
],
[
'ID' => 2,
'post_title' => 'Post Two'
'color' => [
'post_id' => 2,
'name' => 'color',
'value' => 'green'
]
]
]
并执行以下查询。
select * from posts select * from postmeta where post_id in (1, 2)
一对多
一对多关系用于定义一个项目有一个或多个子项的关系。例如,一篇帖子可能有无限数量的评论。要在查询构建器中使用一对多关系,只需使用withMany方法。
DB::table('posts')->withMany('comments', function(WithMany $relation){ $relation->from('comments'); }, 'comment_post_ID', 'ID')->get();
示例输出如下:
[
[
'ID' => 1,
'post_title' => 'Post 1'
'comments' => [
[
'comment_post_ID' => 1,
'comment_content' => 'Something',
...
]
]
],
[
'ID' => 2,
'post_title' => 'Post Two'
'comments' => [
[
'comment_post_ID' => 2,
'comment_content' => 'Something',
...
]
]
]
]
并执行以下两个查询:
select * from posts select * from comments where comment_post_ID in (1, 2)