蜡框架/数据库

此包已被废弃,不再维护。作者建议使用 wpmvc/database 包。

1.0.0 2024-01-01 11:05 UTC

This package is auto-updated.

Last update: 2024-02-21 16:52:46 UTC


README

Total Downloads Latest Stable Version License

关于蜡框架数据库

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

安装

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

composer require waxframework/database

创建Eloquent模型

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

<?php

namespace WaxFramework\App\Models;

use WaxFramework\Database\Eloquent\Model;
use WaxFramework\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();

读取数据

要检索数据,蜡框架数据库提供了各种方法:获取所有帖子

聚合

查询构建器还提供了各种方法来检索聚合值,如count(计数)、max(最大值)、min(最小值)、avg(平均值)和sum(总和)。您可以在构建查询后调用这些方法中的任何一个。

$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表的id列和contacts表的user_id列来连接users表和contacts表。我们还选择了users表的所有列以及contacts表的phoneemail列。

您甚至可以使用多次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列作为连接约束在usersposts表上执行“右连接”,可以执行以下操作:

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

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

高级连接子句

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

use WaxFramework\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子句

要仅获取已发布的帖子或如果post_title是test post,请使用下面的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》方法允许您根据指定列对查询结果进行排序。该方法接受的第一个参数应该是您希望排序的列,而第二个参数用于确定排序方向,可以是《asc》(升序)或《desc》(降序)。

$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_by》和《having》方法可用于对查询结果进行分组。《having》方法的签名与《where》方法相似。

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

限制与偏移

《limit》与《offset》方法

您可以使用《limit》和《offset》方法来限制查询返回的结果数量或跳过查询中的指定数量结果。

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

关系

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

一对一

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

<?php

namespace WaxFramework\App\Models;

use WaxFramework\Database\Eloquent\Model;
use WaxFramework\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 WaxFramework\App\Models;

use WaxFramework\Database\Eloquent\Model;
use WaxFramework\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 WaxFramework\App\Models;

use WaxFramework\Database\Eloquent\Model;
use WaxFramework\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 WaxFramework\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();

许可证

WaxFramework 数据库是开源软件,根据 MIT 许可证 许可。