wpmvc/database

1.1.1 2024-09-27 17:08 UTC

This package is auto-updated.

Last update: 2024-09-27 17:10:57 UTC


README

Total Downloads Latest Stable Version License

关于 WpMVC Database

WpMVC Database 是一个强大的、灵活的 SQL 查询构建器,专门为 WordPress 插件设计。它提供了类似于 Laravel 的 Eloquent Query Builder 的体验,这是一个知名且广泛使用的 PHP 框架。

安装

要安装 WpMVC Database 包,只需通过 Composer 运行以下命令

composer require wpmvc/database

创建 Eloquent 模型

要创建一个 Eloquent 模型,您可以使用以下代码片段。

<?php

namespace WpMVC\App\Models;

use WpMVC\Database\Eloquent\Model;
use WpMVC\Database\Resolver;

class Post extends Model {

	public static function get_table_name():string {
		return 'posts';
	}

	public function resolver():Resolver {
		return new Resolver;
	}
}

插入数据

您可以使用 Eloquent 提供的查询构建器向 posts 表中插入数据。以下是如何插入单个项目的示例

Post::query()->insert([
	'post_author' => wp_get_current_user()->ID,
	'post_title' => "Test Post"
	...
]);
		

要一次性插入多个项目,只需传递一个数组数组

$post_author = wp_get_current_user()->ID;

Post::query()->insert([
	[
		'post_author' => $post_author,
		'post_title' => "Test Post 1"
		...
	],
	[
		'post_author' => $post_author,
		'post_title' => "Test Post 2"
		...
	]
]);

您还可以使用 insert_get_id 方法一步插入一个项目并检索其 ID

$post_id = Post::query()->insert_get_id([
	'post_author' => wp_get_current_user()->ID,
	'post_title' => "Test Post"
	// ...
]);

更新数据

要更新 post_id 为 100 的帖子,请使用以下代码

Post::query()->where('post_id', 100)->update([
	'post_title' => "Test Post"
]);

删除数据

要删除 post_id 为 100 的帖子,请使用以下代码

Post::query()->where('post_id', 100)->delete();

读取数据

要检索数据,WpMVC Database 提供了各种方法:获取所有帖子

聚合

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

$posts = Post::query()->count();

检索模型

所有记录

要获取所有帖子,请使用以下 get 方法

$posts = Post::query()->get();

单个记录

要检索数据库中的单个记录,请使用以下 first 方法

$posts = Post::query()->where('id', 100)->first();

选择语句

您可能不总是想从数据库表中选择所有列。使用 select 方法,您可以为查询指定自定义的 "选择" 子句

$posts = Post::query()->select('post_title', 'post_date')->get();

distinct 方法允许您强制查询返回不同的结果

$posts = Post::query()->distinct()->select('post_title', 'post_date')->get();

连接

内部连接子句

要使用查询构建器向 SQL 查询中添加连接子句,您可以使用 join 方法。此方法用于在两个或更多数据库表之间执行内部连接。传递给 join 方法的第一个参数是要连接的表的名称,其余参数指定连接的列约束。

$users = User::query()
                ->join('contacts', 'users.id', '=', 'contacts.user_id')
                ->select('users.*', 'contacts.phone', 'contacts.email')
                ->get();

在这个例子中,我们将 users 表与 contacts 表连接,连接的是 users 的 id 列和 contactsuser_id 列。我们还选择了 users 的所有列和 contactsphoneemail 列。

您甚至可以在单个查询中使用 join 方法多次连接多个表。例如

$users = User::query()
                ->join('contacts', 'users.id', '=', 'contacts.user_id')
                ->join('orders', 'users.id', '=', 'orders.user_id')
                ->select('users.*', 'contacts.phone', 'orders.price')
                ->get();

在这个示例中,我们将users表与contacts表和orders表进行连接。我们从users表中选择所有列,从contacts表中选择电话列,从orders表中选择价格列。

以下是使用连接方法连接两个表的示例

左连接/右连接子句

要执行“左连接”或“右连接”而不是“内连接”,您可以使用相应的left_joinright_join方法。这些方法与join方法具有相同的签名,这意味着您需要将您想连接的表名作为第一个参数传递,然后指定连接约束的其余参数。

例如,要使用user_id列作为连接约束,对usersposts表执行“左连接”,您可以这样做

$users = User::query()
            ->left_join('posts', 'users.id', '=', 'posts.user_id')
            ->get();

这将返回users表中的所有行以及基于user_id列的匹配行。如果一个用户没有匹配的帖子,则posts表中的值将是NULL

同样,要使用user_id列作为连接约束,对users和posts表执行“右连接”,您可以这样做

$users = User::query()
            ->right_join('posts', 'users.id', '=', 'posts.user_id')
            ->get();

这将返回posts表中的所有行以及基于user_id列的匹配行。如果一个帖子没有匹配的用户,则users表中的值将是NULL

高级连接子句

您还可以指定更复杂的连接子句。要开始,请将闭包作为join方法的第二个参数传递。闭包将接收一个WpMVC\Database\Query\JoinClause实例,这允许您指定“连接”子句的约束

use WpMVC\Database\Query\JoinClause;

$posts = Post::query()->join('postmeta', function (JoinClause $join) {
	$join->on('postmeta.post_id', '=', 'posts.ID')->orOn(/* ... */);
})->get();

如果您想在连接中使用“where”子句,可以使用由JoinClause实例提供的whereor_where方法。与比较两个列不同,这些方法将列与一个值进行比较

$posts = Post::query()->join('postmeta', function (JoinClause $join) {
	$join->on('postmeta.post_id', '=', 'posts.ID')->where('postmeta.meta_value', '>', 500);
})->get();

基本 WHERE 子句

WHERE 子句

要只获取已发布的帖子,请使用以下所示的where方法

$posts = Post::query()->where('post_status', 'publish')->get();

OR WHERE 子句

要获取已发布的帖子或如果帖子标题是测试帖子,请使用以下所示的where方法

$posts = Post::query()->where('post_status', 'publish')->orWhere('post_title', 'test post')->get();

高级 WHERE 子句

WHERE EXISTS 子句

where_existswhere_column方法在您需要从具有公共列的两个不同表中检索数据时非常有用。

要获取所有帖子,如果帖子有元数据,可以使用以下两种方法中的任何一种

  1. 第一种方法:在这个过程中,我们使用闭包函数定义一个子查询,从postmeta表中选择1,其中postmeta表中的post_id列等于posts表中的ID列。闭包函数作为参数传递给where_exists方法以过滤帖子。

    $posts = Post::query()->where_exists(function(Builder $query) {
    	$query->select(1)->from('postmeta')->where_column('postmeta.post_id', 'posts.id')->limit(1);
    })->get();
  2. 另一种方法:我们首先定义一个变量$post_meta,从postmeta表中选择1,其中postmeta表中的post_id列等于posts表中的ID列。然后我们使用where_exists方法和传递$post_meta变量作为参数来过滤帖子。

    $post_meta = PostMeta::query()->select(1)->where_column('postmeta.post_id', 'posts.id')->limit(1);
    $posts     = Post::query()->where_exists($post_meta)->get();

在这两种方法中,我们都使用where_column方法指定两个表中应进行比较的列名。这允许我们根据帖子是否有元数据来过滤帖子。

附加 WHERE 子句

where_between / or_where_between

where_between方法验证列的值是否介于两个值之间

$posts = Post::query()->where_between('ID', [1, 100])->get();

where_not_between / or_where_not_between

where_not_between方法验证列的值是否不在两个值之间

$posts = Post::query()->where_not_between('ID', [1, 100])->get();

where_in / where_not_in / or_where_in / or_where_not_in

where_in方法验证给定列的值是否包含在给定的数组中

$posts = Post::query()->where_in('ID', [100, 105])->get();

where_not_in 方法用于验证给定列的值是否不在给定的数组中。

$posts = Post::query()->where_not_in('ID', [100, 105])->get();

排序、分组、限制与偏移

排序

order_by 方法

order_by 方法允许您按给定列对查询结果进行排序。order_by 方法接受的第一个参数应该是您想要排序的列,而第二个参数确定排序的方向,可以是 ascdesc

$posts = Post::query()->order_by('post_title')->get();

要按多个列排序,您只需多次调用 order_by 即可。

$posts = Post::query()->order_by('post_title')->order_by_desc('post_status')->get();

分组

group_by & having 方法

正如您所期望的,group_byhaving 方法可以用于对查询结果进行分组。与 where 方法类似,having 方法的签名也是相似的。

$posts = Post::query()->group_by('post_author')->having('post_author', '>', 100)->get();

限制与偏移

limit & offset 方法

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

$posts = Post::query()->offset(10)->limit(5)->get();

关系

数据库表通常相互关联。例如,一篇文章可能有多个评论,或者一个订单可能与下订单的用户相关。Eloquent 使得管理和使用这些关系变得简单,并支持各种常见的关系。

一对一

一对一关系是一种非常基本的数据库关系类型。例如,一个 User 模型可能关联一个 Phone 模型。为了定义这种关系,我们将在 User 模型上放置一个 Phone 方法。该 Phone 方法应该调用 has_one 方法并返回其结果。has_one 方法通过模型的 WpMVC\Database\Eloquent\Model 基类对您的模型可用。

<?php

namespace WpMVC\App\Models;

use WpMVC\Database\Eloquent\Model;
use WpMVC\Database\Eloquent\Relations\HasOne;

class User extends Model {

	/**
     * Get the phone associated with the user.
     */
    public function phone(): HasOne
    {
        return $this->has_one(Phone::class, 'ID', 'user_id');
    }
}

Eloquent 假设外键应该有一个值,与父表的键列匹配。换句话说,Eloquent 将在 Phone 记录的 user_id 列中查找用户的 ID 列的值。

现在,让我们检索所有用户及其电话。

$users = User::query()->with('phone')->get();

一对多

一对一关系用于定义一个模型是父模型的单个模型或多个子模型的关系。例如,一篇文章可能有无限数量的元数据。像所有其他 Eloquent 关系一样,一对一关系通过在您的 Eloquent 模型上定义一个方法来定义。

<?php

namespace WpMVC\App\Models;

use WpMVC\Database\Eloquent\Model;
use WpMVC\Database\Eloquent\Relations\HasMany;

class Post extends Model {

	/**
     * Get the all meta associated with the user.
     */
    public function meta(): HasMany
    {
        return $this->has_many(PostMeta::class, 'ID', 'post_id');
    }
}

一对多(反向)/ 属于

现在,我们能够访问所有文章的元数据,让我们定义一个关系,允许元数据访问其父文章。要定义 has_many 关系的逆关系,在子模型上定义一个关系方法,该方法调用 belongs_to_one 方法。

<?php

namespace WpMVC\App\Models;

use WpMVC\Database\Eloquent\Model;
use WpMVC\Database\Eloquent\Relations\BelongsToOne;

class PostMeta extends Model {

	/**
     * Get the post that owns the meta.
     */
    public function post(): BelongsToOne
    {
        return $this->belongs_to_one(Post::class, 'post_id', 'ID');
    }
}

约束查询加载

有时您可能想要一个关系,但也需要为关系查询指定额外的查询条件。您可以通过将包含关系名称作为数组键和闭包作为数组值的数组传递给 with 方法来完成此操作,该闭包为关系查询添加额外的约束。

use WpMVC\Database\Query\Builder;

$posts = Post::query()->with('meta', function(Builder $query) {
	$query->where('meta_id', 672);
})->get();

with 方法中,您可以传递多个关系的数组。

$posts = Post::query()->with([
			'meta' => function (Builder $query) {
				$query->where('meta_id', 672);
			},
			'user'
		])->get();

许可证

WpMVC 数据库是开源软件,许可协议为 MIT 协议