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)