atlas/transit

数据源域映射系统。

0.2.0-alpha 2018-11-27 21:55 UTC

README

从 Atlas 持久化记录和记录集移动数据到域实体、聚合和集合;然后再返回。

  • 使用源记录中的字段值创建域实体和聚合;从域实体和聚合属性更新源记录字段;在源插入后刷新实体以自动递增值。

  • 从记录集中的记录创建域集合成员;从域集合成员更新记录集中的记录。

  • 允许在记录和域对象之间进行常见情况转换(例如 snake_casecamelCasePascalCase);在记录侧默认为 snake_case,在域侧默认为 camelCase

  • 允许在源记录和域对象之间自定义值转换。

  • 提供 select($domainClass) ... ->fetchDomain() 功能,以流畅地从 Atlas.Orm 查询创建域对象。

Atlas.Transit 依赖于域实现中的多个约定

  • 您可以构建一个完整的实体或聚合,仅从单个记录的值(即记录的行和相关项)中构建。

  • 域实体和聚合使用构造函数参数创建,并且构造函数参数名称与内部属性名称相同。

  • 聚合具有其聚合根(即其根实体)作为其第一个构造函数参数。

  • 集合使用成员类名后缀为 'Collection'。 (注意:这是为了让 Transit 能够找到映射器;如果您愿意,您可以使用 @Atlas\Transit\Source\Mapper 注解指定映射器。)

  • 集合接受单个构造函数参数:集合中成员对象的数组。

  • 集合是可遍历的/可迭代的,并在这样做时返回成员对象。

最后,与 Atlas.Orm 及其支持包不同,Atlas.Transit 对注解的使用相对较少;这是为了帮助将域层与持久层尽可能分离。按照以下方式注解您的域类,以帮助 Transit 识别其在域中的用途

  • 实体用 @Atlas\Transit\Entity 注解
  • 集合用 @Atlas\Transit\Collection 注解
  • 聚合用 @Atlas\Transit\Aggregate 注解
  • 值对象用 @Atlas\Transit\ValueObject 注解

默认情况下,您的实体类假定与您的持久化映射器类具有相同的名称。例如,名为 Thread 的域类自动使用名为 Thread 的源映射器类。如果您的实体类使用不同的源映射器,请添加完全限定的映射器类名

/**
 * @Atlas\Transit\Entity App\DataSource\Other\Other
 */

示例

$transit = Transit::new(
    Atlas::new('sqlite::memory:'),
    'App\\DataSource\\', // data source namespace
);

// select records from the mappers to create entities and collections
$thread = $transit
    ->select(Thread::CLASS) // the domain class
    ->where('id = ', 1)
    ->fetchDomain();

$responses = $transit
    ->select(Responses::CLASS) // the domain class
    ->where('thread_id IN ', [2, 3, 4])
    ->fetchDomain();

// do stuff to $thread and $responses

// then plan to save/update all of $responses ...
$transit->store($responses);

// ... and plan to delete $thread
$transit->discard($thread);

// finally, persist all the domain changes in Transit
$success = $transit->persist();

值对象

对于嵌入的值对象,您需要在每个值对象中实现以下方法以在源记录对象中移动。以下示例代码是最基本的示例。

/**
 * @Atlas\Transit\ValueObject
 * @Atlas\Transit\Factory self::transitFactory()
 * @Atlas\Transit\Updater self::transitUpdater()
 */
class ...
{
    private static function transitFactory(object $record, string $field) : self
    {
        return new self($record->$field);
    }

    private static function transitUpdater(self $domain, object $record, string $field) : void
    {
        $record->$field = $domain->$field;
    }
}

注意,使用基于记录的值对象将非常复杂且容易出错。由于数据模型的复杂性和基于记录的值对象的限制,建议谨慎使用。以下是如何使用提供的代码实现值对象的示例。