在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中文網其他相關文章!