实体公共字段的学说继承

2024-02-08

我在我的 Web 项目中使用 Zend Framework 3 和 Doctrine ORM。

我的应用程序中有几个模块(User, Stock, Sales)以及每个模块上的一些实体模型:

  • User模块实体:User, Account, etc..
  • Stock模块实体:SKU, StockLevel, etc..
  • Sales模块实体:Invoice, PaymentMethod, etc..

默认情况下,所有实体都有公共字段,例如:

  • creationDateTime:创建日期/时间
  • creationUser:创建实体的用户
  • lastChangeDateTime:上次实体更改的日期/时间
  • lastChangeUser:最后更改实体的用户

我不想放置这些字段或每个实体,而是创建一个项目基类来扩展我的所有实体。我需要有适用于所有实体的通用方法,即:

  /**
   * Update the last change fields
   * @param string $user User that is updating 
   */
  public void updateLastChange($user)
  {
      $this->lastChageDataTime = \Datetime();
      $this->lastChangeUser = $user;
  }

我所看到的从文档中 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html,看来我需要使用单表继承,但我不知道具体如何使用。问题:

a)通过使用单表继承,Doctrine 会在数据库中为这些字段创建一个基表,还是会连接每个实体表的基表和实体字段,或者换句话说,我将只有实体表还是此继承将创建一个数据库表的基本字段也?

b)我应该将基本实体放在哪里,以便不同模块上的所有实体都可以继承它?

如果有人可以提供一些关于如何做到这一点的示例/链接,我将不胜感激。


对于您想做的事情,单表继承不是您所需要的。

有 2 个选项:

1)MappedSuperClass(几乎直接来自文档)

你做一个MappedSuperClass(文档可以在章节中找到6.1: 映射的超类 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html#mapped-superclasses),然后在该基类中添加这些公共字段。然后,您可以从基类(映射的超类)扩展需要这些字段的所有类。

/** 
 * @MappedSuperclass 
 */
class MappedSuperclassBase
{
    /** @Column(type="datetime") */
    protected $creationDateTime;

    /** 
     * @ManyToOne(targetEntity="Application\Entity\User") 
     * @JoinColumn(name="created_by", referencedColumnName="id")
     */
    protected $creationUser;

    /** @Column(type="datetime") */
    protected $lastChangeDateTime;

    /** 
     * @ManyToOne(targetEntity="Application\Entity\User") 
     * @JoinColumn(name="updated_by", referencedColumnName="id")
     */
    protected $lastChangeUser;

    // ... more fields and methods
}

/** 
 * @Entity 
 */
class EntitySubClass extends MappedSuperclassBase
{
    /** @Id @Column(type="integer") */
    private $id;

    // ... more fields and methods
}

2)你使用一个特质

您创建一个特征(或每个字段/关联的几个单独的特征),在需要具有这些公共字段的所有类中使用。

trait BaseTrait
{
    /** @Column(type="datetime") */
    protected $creationDateTime;

    /** 
     * @ManyToOne(targetEntity="Application\Entity\User") 
     * @JoinColumn(name="created_by", referencedColumnName="id")
     */
    protected $creationUser;

    /** @Column(type="datetime") */
    protected $lastChangeDateTime;

    /** 
     * @ManyToOne(targetEntity="Application\Entity\User") 
     * @JoinColumn(name="updated_by", referencedColumnName="id")
     */
    protected $lastChangeUser ;

    // ... more fields and methods
}

/** 
 * @Entity 
 */
class EntitySubClass
{
    use BaseTrait;

    /** @Id @Column(type="integer") */
    private $id;

    // ... more fields and methods
}

对您问题的答复:

a)在文档中您可以阅读:

单表继承是一种继承映射策略,其中层次结构的所有类都映射到单个数据库表。为了区分哪一行代表层次结构中的哪种类型,使用所谓的鉴别器列。

这意味着所有这些实体将共享一个公共表,这绝对不是您想要的。它可能会变成一个巨大的表(每个实体一行),从而减慢查询速度。除此之外,表中还会有以下列:所有不常见的共享字段这些列将为空(null) 对于没有这些字段的实体。这也意味着那些不共享的字段不能有null约束。再次直接来自文档:

为了使单表继承在使用旧数据库模式或自行编写的数据库模式的情况下工作,您必须确保所有列不在根实体中,而是在任何不同的子实体中必须允许空值。具有 NOT NULL 约束的列必须位于单表继承层次结构的根实体上。

这种继承仅对于类似于很大范围的实体是必要的,并且不适合您在问题中讨论的示例。

b)您可以只添加基本实体(因此MappedSuperClass)在一个常见的模型中(比如你的Application文件夹)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实体公共字段的学说继承 的相关文章

  • 在php中获取二进制数据大小的正确方法是什么?

    我已阅读文件的一部分 现在想确保该部分的大小正确 我怎样才能在 php 中做到这一点 part fread file 1024 return some function part 1024 我已经阅读了这些示例 但我怀疑是否要使用 strl
  • PHP 有效读取 csv 文件

    有几种使用 PHP 读取 CSV 文件的方法 我以前用过explode函数将每一行放入一个数组中 然后explode逗号并使用trim删除数据周围的任何引号 本来就很乱 PHP 5 现在有fgetcsv和 str getcsv 我猜这是这些
  • 永久铸造到超类

    If class Car Automobile 我可以 Car toyota new Car Automobile tauto Automobile toyota 但如果我这样做tauto GetType Name仍然会是Car 是否可以执
  • Extjs:通过构造函数或 initComponent 扩展类?

    在 extjs 中 你总是可以通过以下方式扩展 extjs 类constructor 对于派生自的类Component您还可以通过以下方式扩展initComponent 我想知道为什么这么多代码通过扩展initComponent 然而con
  • Instagram 如何使用 Amazon S3?

    在将文件上传到 Amazon S3 时 我需要深入了解 Instagram 的工程 我刚刚开始使用 S3 我认为 Instagram 是一个值得效仿的好模式 因为他们每天上传数千张图片 我的应用程序有点相似 用户上传图片 可以删除自己的图片
  • 基于 PHP 的 CSV 编辑器? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有谁知道用 PHP 编写的在线 CSV 编辑器允许用户打开 编辑和保存给定的 CSV 文件 我能找到的只
  • 在 symfony2 中为特定控制器设置 max_execution_time

    Using ini set 我可以扩展最大执行时间一个脚本的 在Symfony2 我可以添加ini set to web app php and web app dev php将增加的执行时间应用于所有控制器 但在这种情况下 我只想扩展最大
  • php 在内容前插入十六进制字符数

    我正在将网站移动到新服务器 旧服务器有 php 5 3 2 新服务器有 php 5 5 9 Centos httpd Apache 2 2 26 我已经复制了文件 它工作正常 除了唯一奇怪的事情 一些奇怪的十六进制数字被插入到页面内容之前
  • 为什么我应该使用 $_GET 和 $_POST 而不是 $_REQUEST? [复制]

    这个问题在这里已经有答案了 除此之外 REQUEST从 cookie 读取 有什么理由我应该使用 GET and POST代替 REQUEST 这样做的理论和实践理由是什么 当我只想让用户的某些数据返回某些数据时 我使用 REQUEST 当
  • 如何将 ctype_alpha 与 UTF-8 结合使用

    如何将 ctype alpha 与 UTF 8 一起使用 我有这个代码 if empty POST false if isset POST first name empty POST first name if ctype alpha PO
  • 适用于 Windows 的 PHP 支持的 GUI 应用程序

    我知道 PHP 是一种解释性语言 对于基于 Web 的事物来说 不是为在实际操作系统上运行 GUI 应用程序而设计的 但是有没有办法呢 基本上 是否有一个框架 系统允许我创建 本机 基本上是二进制文件 exe 看起来像带有本机控件和所有内容
  • Propel Query 中的动态表名称

    我想知道您是否可以使 propel 查询的表名称动态化 有点像变量 一个例子类似于 DynamicVar Query create 我让它在 ifs 中工作 就像下面的例子一样 但如果更动态地制作 可以删除相当多的行 这些表的设置都是相同的
  • ADO EF Code First 通用中间类继承映射

    我有以下要求 该要求在 OO 空间中运行良好 但我似乎无法首先使用 ADO EF 代码将其映射回数据库 我有许多产品 每个产品都有不同的方面 属性 但不是代码属性意义上的 例如 戒指将具有矿物类型 金等方面 而钻石将具有净度方面 VVSI1
  • 如何在 joomla 模块中通过 javascript 发送输入文件类型

    我想将带有 javascript 的文件发送到 php 文件 我的 php 文件中有这个表单
  • 疯狂的 crond 行为。不断使 bash 进程失效

    我有一个看起来像这样的 crontab SHELL bin bash PATH sbin bin usr sbin usr bin MAILTO root HOME 0 59 var www html private fivemin zda
  • 从多个选择列表中插入数据到mysql数据库(html形式)

    我制作了一个表格 其中有商店的 ID
  • 从外部 bash 设置环境变量

    我试图使用 PHP 从命令行 设置 bash 环境变量 但没有成功 buff array buff VARTESTKEY VARTESTVALUE buff export VARTESTKEY file put contents scrip
  • $_SESSION 中保存大量信息可以吗?

    我需要存储许多数组 SESSION以防止从 MySQL 检索信息 可以吗 其中 太多 的信息有多少 SESSION还是没有 太多 谢谢 附 或者更好地使用http php net manual en book memcache php ht
  • Laravel 5 注销特定用户

    在我的 laravel 5 应用程序中 有一个功能允许具有管理员角色的用户重置非管理员的任何人的密码 但这不会强制该人注销并再次登录 更改密码后如何强制用户注销 我没有对用于验证用户身份或任何内容的中间件进行任何更改 我不知道它是否有效 但
  • 处理查询字符串参数时 Codeigniter 缓存问题

    问候 我正在编写一个 CI Web 应用程序 它实现标准文件缓存功能 如下所示 this gt output gt cache n 我使用了段和查询字符串参数的组合 因此似乎遇到了问题 我在用例和输出类代码中看到的是 缓存仅基于段 像这样

随机推荐