在 Doctrine2 中,处理多对多关系需要仔细考虑,尤其是当有额外列时涉及参考表。虽然建议的双重一对多关系方法可能有效,但它在访问所需数据方面带来了潜在的挑战。
考虑专辑和曲目的示例曲目,其中我们需要与额外列的多对多关系,例如曲目在专辑中的位置和升级状态。映射看起来像这样:
class Album { /** @OneToMany(targetEntity="AlbumTrackReference", mappedBy="album") */ protected $tracklist; } class Track { /** @OneToMany(targetEntity="AlbumTrackReference", mappedBy="track") */ protected $albumsFeaturingThisTrack; } class AlbumTrackReference { /** @ManyToOne(targetEntity="Album", inversedBy="tracklist") */ protected $album; /** @ManyToOne(targetEntity="Track", inversedBy="albumsFeaturingThisTrack") */ protected $track; /** @Column(type="integer") */ protected $position; /** @Column(type="boolean") */ protected $isPromoted; }
Album::getTracklist() 方法返回一个 AlbumTrackReference 对象数组而不是 Track 对象,使得访问特定于轨道的信息变得具有挑战性。虽然代理方法或方法中的额外处理等选项可以提供解决方案,但它们可能很麻烦且效率低下。
建议的替代方法Doctrine 社区将多对多关系视为一个实体。这使我们能够为参考表创建一个专用实体,在专辑和曲目实体之间具有一对多和多对一的关系。
class AlbumTrackReference { /** @Id @Column(type="integer") */ protected $id; /** @ManyToOne(targetEntity="Album") */ protected $album; /** @ManyToOne(targetEntity="Track") */ protected $track; /** @Column(type="integer") */ protected $position; /** @Column(type="boolean") */ protected $isPromoted; }
这种方法通过提供直接的数据检索来简化数据检索通过AlbumTrackReference 实体访问曲目和专辑信息。代码可以变成:
foreach ($album->getTracklist() as $albumTrackReference) { $track = $albumTrackReference->getTrack(); echo sprintf("\t#%d - %-20s (%s) %s\n", $albumTrackReference->getPosition(),
以上是Doctrine2中如何高效处理带有额外列的多对多关系?的详细内容。更多信息请关注PHP中文网其他相关文章!