为了账号安全,请及时绑定邮箱和手机立即绑定

Doctrine 2:在引用表中使用额外列处理多到多列的最佳方法

Doctrine 2:在引用表中使用额外列处理多到多列的最佳方法

PHP
慕娘9325324 2019-07-05 09:26:25
Doctrine 2:在引用表中使用额外列处理多到多列的最佳方法我想知道什么是最好的,最干净的,最简单的方式来处理多到多的关系在原则2。假设我们有一张专辑木偶大师金属有几个脚印。但请注意,一首歌可能会出现在更多的专辑中,比如电池金属有三张专辑都是以这首歌为特色的。所以我需要的是专辑和曲目之间的多对多的关系,使用第三个表和一些额外的列(比如在指定相册中的曲目位置)。实际上,正如Doctrine的文档所建议的那样,我必须使用一对多的双重关系来实现这一功能。/** @Entity() */class Album {     /** @Id @Column(type="integer") */     protected $id;     /** @Column() */     protected $title;     /** @OneToMany(targetEntity="AlbumTrackReference", mappedBy="album") */     protected $tracklist;     public function __construct() {         $this->tracklist = new \Doctrine\Common\Collections\ArrayCollection();     }     public function getTitle() {         return $this->title;     }     public function getTracklist() {         return $this->tracklist->toArray();     }}/** @Entity() */class Track {     /** @Id @Column(type="integer") */     protected $id;     /** @Column() */     protected $title;     /** @Column(type="time") */     protected $duration;     /** @OneToMany(targetEntity="AlbumTrackReference", mappedBy="track") */     protected $albumsFeaturingThisTrack; // btw: any idea how to name this relation? :)     public function getTitle() {         return $this->title;     }     public function getDuration() {         return $this->duration;     }}/** @Entity() */class AlbumTrackReference {     /** @Id @Column(type="integer") */     protected $id;     /** @ManyToOne(targetEntity="Album", inversedBy="tracklist") */     protected $album;     /** @ManyToOne(targetEntity="Track", inversedBy="albumsFeaturingThisTrack") */     protected $track;     /** @Column(type="integer") */     protected $position;     /** @Column(type="boolean") */     protected $isPromoted;     public function getPosition() {         return $this->position;     }     public function isPromoted() {         return $this->isPromoted;     }     public function getAlbum() {         return $this->album;     }     public function getTrack() {         return $this->track;     }}
查看完整描述

3 回答

?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

class AlbumTrackReference {
    public function getTitle() {
        return $this->getTrack()->getTitle()
    }}

这是个好主意,但我使用的是来自双方的“引用对象”:$album->getTracklist()[12]->getTitle()$track->getAlbums()[1]->getTitle(),所以getTitle()方法应该根据调用的上下文返回不同的数据。

我得做这样的事:

 getTracklist() {
     foreach ($this->tracklist as $trackRef) { $trackRef->setContext($this); }
 }

 // ....

 getAlbums() {
     foreach ($this->tracklist as $trackRef) { $trackRef->setContext($this); }
 }

 // ...

 AlbumTrackRef::getTitle() {
      return $this->{$this->context}->getTitle();
 }

这不是一种非常干净的方式。


查看完整回答
反对 回复 2019-07-05
?
慕姐8265434

TA贡献1813条经验 获得超2个赞

从$相册->getTrackList()中,您将获得“Al猝发TrackReference”实体返回,那么从Track和Proxy添加方法怎么样?

class AlbumTrackReference{
    public function getTitle()
    {
        return $this->getTrack()->getTitle();
    }

    public function getDuration()
    {
        return $this->getTrack()->getDuration();
    }}

这样,您的循环以及与循环专辑轨道相关的所有其他代码都大大简化了,因为所有方法都只是在AlbunTrakcReference中进行代理:

foreach ($album->getTracklist() as $track) {
    echo sprintf("\t#%d - %-20s (%s) %s\n", 
        $track->getPosition(),
        $track->getTitle(),
        $track->getDuration()->format('H:i:s'),
        $track->isPromoted() ? ' - PROMOTED!' : ''
    );}

顺便说一句,你应该重命名“白蛋白轨迹参考”(例如,“白蛋白轨迹”)。显然,它不仅是一种引用,而且还包含额外的逻辑。因为有可能也有轨道,不是连接到一个专辑,但只有通过一个宣传CD或其他什么,这也允许一个更干净的分离。


查看完整回答
反对 回复 2019-07-05
  • 3 回答
  • 0 关注
  • 468 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信