设计模式 Doctrine ORM - 根据输入生成唯一名称

Posted

技术标签:

【中文标题】设计模式 Doctrine ORM - 根据输入生成唯一名称【英文标题】:Design pattern Doctrine ORM - Generate unique names based on input 【发布时间】:2016-02-13 18:06:18 【问题描述】:

我正在使用 Symfony2 和 Doctrine ORM,并希望通过简洁的架构实现以下目标:

每次创建新实体时,我都想保存最终用户选择的“显示名称”,然后根据“显示名称”生成一个“唯一名称”。

如果我的最终用户想要创建 3 个名为“Drawings”的项目,

第一个将具有 display_name = "drawings" 第二个将具有 display_name = "drawings2" 第三个将具有 display_name = "drawings3"

(或类似的东西,不管是什么模式)

基本实体示例:

/**
 * Project.
 *
 * @ORM\Entity
 */
class Project

    //...

    /**
     * @ORM\Column(type="string", length=50, nullable=false)
     */
    protected $name_display ;

    /**
     * @ORM\Column(type="string", length=50, nullable=false, unique=true)
     */
    protected $name_unique ;

    //...

基本用法示例:

$project = new Project();
$project->setDisplayName('Drawings'); 
//Around here I would like the Unique name to be generated
$this->getDoctrine()->getManager()->persist($project);

我想过各种解决方案:

在 Controller 中生成名称,但不可重用 在存储库中生成唯一名称。但这似乎是一种不好的做法(存储库应该是只读的) 使用来自学说的 PrePersist LifecycleCallbacks,但这不是一个好习惯,因为我需要实体管理器来创建数据库 在实体设置器中生成名称,注入实体管理器以发出请求并查找可用名称。这看起来很可怕 使用服务来持久化实体,如下所述:Are Doctrine2 repositories a good place to save my entities?(但如果我想让我的所有实体创建都与这种做法保持一致,它会非常复杂并且涉及到我的基础架构的巨大变化)

【问题讨论】:

【参考方案1】:

我会推荐最后一个选项 - 服务。它可能需要在您的项目中进行更改,但我发现这是使用实体管理常规 crud 操作的最佳方式 - 创建、保存、findBySomething ...

它晶莹剔透——没有黑魔法。与执行代码和实体操作之间没有明显关系的事件相反(例如通过 new 创建它)。 不依赖注解,易于维护。 控制器和其他服务可以通过依赖注入来访问该服务,这是一种满足业务对象(持有业务逻辑的对象)依赖的明确方式 您的存储库不会变得越来越大 您可以使用默认存储库 - 升级 Doctrine 时的向后兼容性问题更少 它比“setter 解决方案”要好得多,这听起来真的很可怕 - 实体永远不应该那么强大,所以它们会引用服务(尤其是像 EntityManager 这样的服务)

【讨论】:

以上是关于设计模式 Doctrine ORM - 根据输入生成唯一名称的主要内容,如果未能解决你的问题,请参考以下文章

从 orm.xml Doctrine 生成 php 实体

ZF2 Skeleton 和 Doctrine ORM xml 模式合并

Symfony 3 Doctrine MySQL - 使用 @ORM 注释生成实体

在 Repository 中使用 Doctrine 2 ORM 和 OneToOne 获得“排名”

Symfony2:传递给 Doctrine\ORM\EntityRepository::__construct() 的参数 2 必须是 Doctrine\ORM\Mapping\ClassMetada

PHP Doctrine 初学者:找不到 Doctrine\ORM\Tools\Setup