activecollab/databaseobject

库,使对象持久化到MySQL 5.7+数据库变得简单

7.0.1 2024-03-09 08:31 UTC

README

Build Status

DatabaseObject库是一组类,使与数据库交互变得简单。以下是关键概念:

  1. 类型 - 映射到单个表的实体
  2. 实体 - 映射到类型表单的某一行类型的实例
  3. 实体管理器 - 提供对自定义类型特定操作方法的实例
  4. 集合 - 满足给定标准的对象组。这个组非常适合HTTP响应,因为集合支持数据标记和标记验证(ETag和HTTP 304)
  5. 池 - 管理注册的类型并使多类型交互成为可能
  6. 生产者 - 定制池产生新实例的方式
  7. 验证器 - 在将对象属性保存到数据库之前验证对象属性

CRUD

如果您希望与整个表一起工作,请使用由ConnectionInterface提供的CRUD方法

  1. ConnectionInterface::insert() - 插入一行或多行
  2. ConnectionInterface::update() - 更新满足给定条件的一组行
  3. ConnectionInterface::delete() - 删除满足给定条件的一组行

当您需要与单个实例一起工作时,PoolInterface提供以下实用方法

  1. PoolInterface::produce() - 根据给定参数创建新记录
  2. PoolInterface::modify() - 使用一组参数更改给定对象
  3. PoolInterface::scrap() - 将给定对象放入垃圾箱或永久删除

Scrap

最近我们添加了ScrapInterface。实现ScrapInterface的模型应该支持对象垃圾回收,而不是立即删除。当调用PoolInterface::scrap()方法时,实现ScrapInterface的对象将被回收(标记为已删除或放入垃圾箱,具体取决于特定实现),而不是永久删除。

Finder

要设置条件,请使用where方法

$pool->find(Writer::class)
     ->where('`birthday` > ?', '1800-01-01')
     ->ids();

此方法可以多次调用,所有条件将使用AND运算符在一个块中连接

$pool->find(Writer::class)
     ->where('`birthday` > ?', '1800-01-01')
     ->where('`birthday` < ?', '1825-01-01')
     ->ids();

Finder可以通过表名或相关类型连接到表

$pool->find(Writer::class)
     ->joinTable('writer_groups')
     ->where('`writer_groups`.`group_id` = ?', $group_id)
     ->ids();

或通过相关类型

$pool->find(Writer::class)
     ->join(WriterGroup::class)
     ->where('`writer_groups`.`group_id` = ?', $group_id)
     ->ids();

注意,在第二种情况下,需要将WriterGroup类型注册到池中。

DI容器

池实现ActiveCollab\ContainerAccess\ContainerAccessInterface,因此您可以设置任何实现Interop\Container\ContainerInterface接口的容器,并且该容器将在查找器、生产者和对象中传递和可用

$container = new Container([
    'dependency' => 'it works!',
]);

$pool->setContainer($container);

foreach ($pool->find(Writer::class)->all() as $writer) {
    print $writer->dependency . "\n"; // Prints it works!
}

生成字段

生成字段是存在于表中的字段,但它们不由实体类本身控制或管理。相反,这些模型的值在其他地方设置

  1. 它们在表定义中指定为生成列
  2. 触发器设置值
  3. 值由外部系统或流程设置

库通过访问器方法提供对这些字段值的访问,但无法使用设置器方法设置这些值

<?php

use ActiveCollab\DatabaseObject\Entity\Entity;

class StatsSnapshot extends Entity
{
    /**
     * Generated fields that are loaded, but not managed by the entity.
     *
     * @var array
     */
    protected $generated_fields = ['is_used_on_day', 'plan_name', 'number_of_users'];
    
    /**
     * Return value of is_used_on_day field.
     *
     * @return bool
     */
    public function isUsedOnDay()
    {
        return $this->getFieldValue('is_used_on_day');
    }

    /**
     * Return value of is_used_on_day field.
     *
     * @return bool
     * @deprecated use isUsedOnDay()
     */
    public function getIsUsedOnDay()
    {
        return $this->getFieldValue('is_used_on_day');
    }

    /**
     * Return value of plan_name field.
     *
     * @return string
     */
    public function getPlanName()
    {
        return $this->getFieldValue('plan_name');
    }

    /**
     * Return value of number_of_users field.
     *
     * @return int
     */
    public function getNumberOfUsers()
    {
        return $this->getFieldValue('number_of_users');
    }
}

在实体配置期间可以设置值转换

<?php

use ActiveCollab\DatabaseConnection\Record\ValueCaster;
use ActiveCollab\DatabaseConnection\Record\ValueCasterInterface;
use ActiveCollab\DatabaseObject\Entity\Entity;

class StatsSnapshot extends Entity
{
    protected function configure(): void
    {
        $this->setGeneratedFieldsValueCaster(new ValueCaster([
            'is_used_on_day' => ValueCasterInterface::CAST_BOOL,
            'plan_name' => ValueCasterInterface::CAST_STRING,
            'number_of_users' => ValueCasterInterface::CAST_INT,
        ]));
    }
}

实体类还会在对象保存时刷新这些字段的值,以便在后台(通过触发器或生成字段表达式)重新计算时立即提供最新值

待办事项

  1. 缓存
  2. 删除已弃用的ObjectInterfaceObject类。