mehedimi / wp-query-builder

WordPress 数据查询构建器

0.15 2024-05-16 15:05 UTC

This package is auto-updated.

Last update: 2024-09-16 15:49:27 UTC


README

WP Query Builder

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 类提供了针对每种查询类型的方法:selectinsertupdatedeletestatementaffectingStatement

运行 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;

聚合

查询构建器还提供了一系列方法来检索聚合值,如 countmaxminavgsum。您可以在构建查询后调用这些方法中的任何一个。

$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",请使用 leftJoinrightJoin 方法。这些方法与 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 实例提供的 whereorWhere 方法。与比较两个列不同,这些方法将列与一个值进行比较

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 列值为 100age 列值大于 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 方法接受的第一个参数应该是您希望排序的列,而第二个参数确定排序的方向,可以是 ascdesc

$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();

限制和偏移

您可以使用 offsetlimit 方法限制查询返回的结果数量,或跳过查询中给定数量的结果

$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可能关联一个名为colorpostmeta。为了定义这种关系,我们只需在查询构建器上调用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)