这是什么框架?! ORM

v0.2.1 2024-09-09 19:25 UTC

This package is auto-updated.

Last update: 2024-09-14 10:57:05 UTC


README

此库扩展了 DBAL 库以提供对象关系映射。

安装

composer require wtframework/orm

文档

创建新模型

通过扩展 WTFramework\ORM\Model 类创建新模型。

use WTFramework\ORM\Model;

class User extends Model {}


默认情况下,表名将是蛇形命名法的类名复数形式。例如,class UserRole 将具有表名 user_roles。如果您想指定表名,请包括 public const TABLE

class User extends Model
{
  public const TABLE = 'x_users';
}


默认情况下,主键将是蛇形命名法的类名后缀为 _id。例如,class UserRole 将具有主键 user_role_id。如果您想指定主键,请包括 public const PRIMARY_KEY。这可能是一个字符串或一个数组(如果是一个复合主键)。

class User extends Model
{
  public const PRIMARY_KEY = 'id';
}


默认情况下,模型将使用在 DBAL 配置设置中定义的默认数据库连接。如果您想指定连接名称,请包括 public const CONNECTION

class User extends Model
{
  public const CONNECTION = 'mirror';
}

插入记录

使用 create 静态方法创建新记录,传入其数据作为 stdClass 对象或数组。这将返回模型的新实例。

$user = User::create(['user_id' => 1]);

选择记录

使用 get 静态方法通过传递主键作为字符串、整数或数组(如果是一个复合主键)来选择记录。

$user = User::get(1);

$user = User::get([
  'id1' => 1,
  'id2' => 2,
]);


使用 exists 方法确定记录是否被找到。

$user->exists();


使用 require 静态方法选择记录,并在记录未找到时抛出 WTFramework\ORM\ModelNotFoundException

$user = User::require(1);

$user = User::require([
  'id1' => 1,
  'id2' => 2,
]);

更新记录

使用 save 方法更新记录。您可以通过手动设置模型属性或传递其数据作为 stdClass 对象或数组来设置数据。

$user->name = 'Michael';

$user->save(['user_role_id' => 1]);

刷新记录

使用 refresh 方法撤销尚未保存到数据库的任何更改。

$user->name = 'Michael';

$user->refresh();


使用 fresh 方法返回记录的新实例。

$user->name = 'Michael';

$fresh = $user->fresh();

查询模型

您可以使用 SQL 库定义的 SELECT 语法中的任何方法来查询模型。然后使用 get 获取单个模型或 all 获取模型数组的结果。

$users = User::where('user_role_id', 1)->all();


模型还提供了快速插入、更新、删除等方法。这些方法中的每一个都返回来自 DBAL 库的流畅接口,用于生成 SQL 语句,并自动使用定义的表。

User::select();
User::insert();
User::replace();
User::update();
User::delete();
User::truncate();

关系

ORM 允许创建 belongs tohashas manyhas throughhas many through 关系。

use WTFramework\ORM\Model;
use WTFramework\ORM\Relationships\BelongsTo;
use WTFramework\ORM\Relationships\Has;
use WTFramework\ORM\Relationships\HasMany;
use WTFramework\ORM\Relationships\HasManyThrough;
use WTFramework\ORM\Relationships\HasThrough;

class User extends Model
{

  public function role(): BelongsTo
  {
    return $this->belongsTo(UserRole::class);
  }

  public function profile(): Has
  {
    return $this->has(Profile::class);
  }

  public function revisions(): HasMany
  {
    return $this->hasMany(UserRevision::class);
  }

  public function owner(): HasOneThrough
  {
    return $this->hasOneThrough(Owner::class, UserOwner::class);
  }

  public function permissions(): HasManyThrough
  {
    return $this->hasManyThrough(Permission::class, UserPermission::class);
  }

}


默认情况下,将使用模型的主键检索记录。如果需要关系使用不同的列名,则可以将它们作为附加参数传递。

class User extends Model
{

  public const PRIMARY_KEY = 'id';

  public function role(): BelongsTo
  {
    return $this->belongsTo(UserRole::class, local_key: 'role_id');
  }

  public function profile(): Has
  {
    return $this->has(Profile::class, foreign_key: 'user_id');
  }

  public function revisions(): HasMany
  {
    return $this->hasMany(UserRevision::class, foreign_key: 'user_id');
  }

  public function owner(): HasOneThrough
  {
    return $this->hasOneThrough(Owner::class, UserOwner::class, foreign_key: 'owner_id', pivot_local_key: 'user_id');
  }

  public function permissions(): HasManyThrough
  {
    return $this->hasManyThrough(Permission::class, UserPermission::class, foreign_key: 'permission_id', pivot_local_key: 'user_id');
  }

}


使用关系方法名称作为属性来返回关系的结果。

$role = $user->role->name;


以这种方式检索关系时,它们将被缓存。使用 clearCache 方法清除缓存。

$user->clearCache();


如果您直接调用关系方法,则它将返回 WTFramework\ORM\Query 的实例,允许您进一步操作结果。

$revisions = $user->revisions()->orderBy('created')->all();


默认情况下,关系将按需加载。这可能导致N+1查询问题。要预加载关系,可以调用eager方法,传入一个字符串或一个预加载关系名称的数组。

User::eager('revisions')->all();


您也可以通过设置public const EAGER数组来实现默认预加载。

class User extends Model
{

  public const EAGER = ['revisions'];

  public function revisions(): HasMany
  {
    return $this->hasMany(UserRevision::class);
  }

}


当默认预加载一个关系时,可以通过调用lazy方法来覆盖此行为。

User::lazy('revisions')->where('user_id', 1)->get();