簡體   English   中英

Doctrine2 ORM訪問多對多聯接表

[英]Doctrine2 ORM Access ManyToMany Join Table

我先前問題的跟進

Doctrine2 ORM OneToOne無法正常工作UPDATE更改為ManyToMany,但無法完全正常工作

我接受了給出的非常有幫助的答案,因為它為我指明了正確的方向。 不幸的是,我很難使其余的工作正常進行,但是由於問題時間太長且令人困惑,所以我提出了一個新問題。

我有一個頁面,用戶可以在其中寫廣告。 用戶還可以在他們希望在其用戶部分中看到的廣告添加書簽。

我有3個數據庫表

advert (id, advert_title....)
user (id, user_name....)
bookmarks (advert_id, user_id)

如上一個問題所述,我創建了2個實體,即廣告和用戶實體(請參見下文)

Advert.php

namespace Advert\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use DateTime;
use Zend\Stdlib\ArrayObject;

/** Advert
 * 
 * @ORM\Table(name="advert")
 * @ORM\Entity(repositoryClass="Advert\Repository\AdvertRepository")
 */

class Advert
{
/**
 * @var integer
 * @ORM\Column(name="id", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
     private $id;

/**
 * @ORM\ManyToMany(targetEntity="Advert\Entity\User", mappedBy="bookmarks", cascade={"persist"})
 * @ORM\JoinTable(name="bookmarks",
 *      joinColumns={@ORM\JoinColumn(name="advert_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}
 *      )
 */
    private $bookmarks;


    public function __construct() 
    { 
        $this->categories = new ArrayCollection();
        $this->images = new ArrayCollection();
        $this->advertCreated = new \DateTime("now");
    }

/** 
 * Set ID 
 * 
 * @param integer $id 
 * @return Advert 
 */ 
    public function setId($id) 
    { 
        $this->id = $id; 
        return $this; 
    }

/**
 * Get id
 *
 * @return integer 
 */
    public function getId()
    {
        return $this->id;
    }

 /**
 * Set bookmark
 *
 * @param  $bookmark
 * @return bookmark
 */
    public function setBookmark($bookmark)
    {
        $this->bookmark = $bookmark;
        return $this;
    }


/**
 * Get bookmark
 *
 * @return ArrayCollection
 */
    public function getBookmark()
    {
        return $this->bookmarks;
    }


/**
 * @param Collection $bookmark
 */
    public function addBookmark($bookmarks)
    {
        $this->bookmarks->add($bookmarks);
    }

/**
 * @param Collection $bookmark
 */
    public function removeBookmark($bookmarks)
    {
        $this->bookmarks->removeElement($bookmarks);     
    }
}

User.php

namespace Advert\Entity;

use Doctrine\ORM\Mapping as ORM;
use ZfcUser\Entity\User as ZfcUser;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;


/**
 * User
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="Advert\Repository\UserRepository")
 */

class User extends ZfcUser
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
protected $id;

/**
 * @ORM\ManyToMany(targetEntity="Advert\Entity\Advert", inversedBy="bookmarks", cascade={"persist"})
 * @ORM\JoinTable(name="bookmarks",
 *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="advert_id", referencedColumnName="id")}
 *      )
 */
 private $bookmarks;


public function __construct()
{
    $this->bookmarks = new ArrayCollection();  
}

public function getBookmarks() {
     return $this->bookmarks;
}

/**
* @param Collection $bookmarks
*/
public function addBookmarks(Collection $bookmarks)
{
   foreach ($bookmarks as $bookmark) {
       $this->bookmarks->add($bookmark);
   }
}

/**
 * @param Collection $bookmarks
 */
public function removeBookmarks(Collection $bookmarks)
{
   foreach ($bookmarks as $bookmark) {
       $this->bookmarks->removeElement($bookmark);
   }
}  
}

我現在有了一項服務,可以檢查廣告是否已被添加書簽,刪除書簽或設置書簽。 這意味着我必須直接在聯接表書簽中輸入UserId和AdvertId。 但是,如果我沒有帶有setUserId和setAdvertId的書簽實體,該怎么辦?

到目前為止,這是我的服務,最后兩種方法(保存和刪除)顯示了刪除書簽實體之前使用的方法。 現在如何讀取聯接表以檢查書簽是否已存在,因此請檢查userId和advertId? 再次,我將如何訪問此表以直接刪除書簽? 如果所有者刪除了廣告,這會刪除書簽,這很不錯,但是顯然,用戶還需要能夠僅刪除書簽。 我該如何實現?

BookmarkAdvertService.php

public function checkAdvertBookmarkStatus($advertId)
{
    $userId = $this->getUserEntity()->getId();  
    $advert = $this->getEntityManager()->find('Advert\Entity\Advert', $advertId);
    $bookmarkStatus= $advert->getBookmark();
    return $bookmarkStatus;
}

public function saveAdvertBookmark($advertId)
{
    //this is what I used before
    $bookmark = new BookmarkEntity();
    $userId = $this->getUserEntity()->getId();

    // $bookmark->addBookmark($advertId); ??? like this
    $bookmark->setAdvertId($advertId);
    $bookmark->setUserId($userId);

    # write new bookmmark to database tbl bookmark
    $this->getEntityManager()->persist($bookmark);
    $this->getEntityManager()->flush();
}


public function removeAdvertBookmark($advertId)
{
    // this is what I used before
    $userId = $this->getUserEntity()->getId();
    $bookmark = $this->getEntityManager()->getRepository('Advert\Entity\Bookmark')
                                         ->findOneBy(array('advertId' => $advertId, 'userId' => $userId));

    # remove bookmmark from tbl bookmark
    $this->getEntityManager()->remove($bookmark);
    $this->getEntityManager()->flush();
}

更新1不起作用

我收到2條錯誤消息:

get_class() expects parameter 1 to be object, string given

vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\MappingException.php:96

Message:

Class '' does not exist

Advert \\ Service \\ BookmarkAdvertService.php

class BookmarkAdvertService 
{

  public function saveAdvertBookmark($advert)
  {
    $user = $this->getUserEntity()->getId(); 

    # create a new, empty entity
    $bookmark = new \Advert\Entity\Bookmark();
    $bookmark->setUser($user);
    $bookmark->setAdvert($advert);
     # write new bookmmark to database tbl bookmark
    $this->getEntityManager()->persist($bookmark);
    $this->getEntityManager()->flush();
  }

廣告/實體/Bookmark.php

namespace Advert\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;

/** Bookmark
 * 
 * @ORM\Table(name="bookmarks")
 * @ORM\Entity(repositoryClass="Advert\Repository\BookmarkRepository")
 */
class Bookmark
{
/**
 * @ORM\Id
 * @ORM\ManyToOne(targetEntity="Advert\Entity\Advert", inversedBy="bookmark")
 * @ORM\JoinColumn(name="advert_id", referencedColumnName="id")
 */
private $advert;

/** 
 * @ORM\Id
 * @ORM\ManyToOne(targetEntity="Advert\Entity\User", inversedBy="bookmark")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 */
private $user;


public function setAdvert($advert)
{
    $this->advert = $advert;
    return $this;
}

public function getAdvert()
{
    return $this->advert;
}


public function setUser($user)
{
    $this->user = $user;
    return $this;
}

public function getUser()
{
    return $this->user;
}    
}

Advert \\ Entity \\ advert.php

namespace Advert\Entity;
use Advert\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/** Advert
 * 
 * @ORM\Table(name="advert")
 * @ORM\Entity(repositoryClass="Advert\Repository\AdvertRepository")
 */
class Advert
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;

/**
 * @ORM\OneToMany(targetEntity="Bookmark", mappedBy="advert", cascade={"persist", "remove"})
 * @ORM\JoinColumn(name="advert_id", referencedColumnName="id")
 */
private $bookmarks;

public function setBookmark($bookmark)
{
    $this->bookmark = $bookmark;
    return $this;
}


/**
 * Get bookmark
 *
 * @return ArrayCollection
 */
public function getBookmarks()
{
    return $this->bookmarks;
}

/**
 * @param Collection $bookmarks
 */
public function removeBookmarks(Collection $bookmarks)
{
  foreach ($bookmarks as $bookmark) {
    $this->bookmarks->removeElement($bookmark);
}
}

Advert \\ Entity \\ User.php

namespace Advert\Entity;

use Doctrine\ORM\Mapping as ORM;
use ZfcUser\Entity\User as ZfcUser;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

/**
 * User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="Advert\Repository\UserRepository")
 */

class User extends ZfcUser
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
 protected $id;

 /**
 * @ORM\OneToMany(targetEntity="Bookmark", mappedBy="user", cascade={"persist", "remove"})
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 */
private $bookmarks;


public function __construct()
{
    $this->bookmarks = new ArrayCollection();
}


public function getBookmarks() 
{
     return $this->bookmarks;
}

/**
* @param Collection $bookmarks
*/
public function addBookmarks(Collection $bookmarks)
{
   foreach ($bookmarks as $bookmark) {
       $this->bookmarks->add($bookmark);
   }
}

/**
* @param Collection $bookmarks
*/
public function removeBookmarks(Collection $bookmarks)
{
   foreach ($bookmarks as $bookmark) {
       $this->bookmarks->removeElement($bookmark);
   }
}

更新2工作

public function saveAdvertBookmark($advertId)
{
    $userId = $this->getUserEntity()->getId(); 
    $user = $this->getEntityManager()->find('Advert\Entity\User', $userId);
    $advert = $this->getEntityManager()->find('Advert\Entity\Advert', $advertId);
     # create a new, empty entity
    $bookmark = new \Advert\Entity\Bookmark();
    $bookmark->setUser($user);
    $bookmark->setAdvert($advert);
     # write new bookmmark to database tbl bookmark
    $this->getEntityManager()->persist($bookmark);
    $this->getEntityManager()->flush();
}


public function removeAdvertBookmark($advert)
{
    $user = $this->getUserEntity()->getId();  
    $advert = $this->getEntityManager()->getRepository('Advert\Entity\Bookmark')
                                         ->findOneBy(array('advert' => $advert, 'user' => $user));
    if ($advert !== NULL){

         # write new bookmmark to database tbl bookmark
        $this->getEntityManager()->remove($advert);
        $this->getEntityManager()->flush();
    }else{
        return false;
    }
}

您的映射似乎錯誤。 在我看來,您的書簽本身也是一個實體。 該實體有一個User和一個Advert 這兩個組合創建了一個復合密鑰。

因此,從UserBookmark的關系是一對多的。 並添加書簽給用戶多對一。

AdvertBookmark的關系是一對多的,從BookmarkAdvert的關系是多對一的。

您的Bookmark實體應如下所示:

class Bookmark
{
    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Advert\Entity\Advert", inversedBy="bookmarks")
     * @ORM\JoinColumn(name="advert_id", referencedColumnName="id")
     */
    private $advert;

    /** 
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="User\Entity\User", inversedBy="bookmarks")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    private $user;

    /**
     * @param Advert $advert
     * @return self
     */
    public function setAdvert(Advert $advert)
    {
        $this->advert = $advert;
        $advert->addBookMark($this);
        return $this;
    }

    /**
     * @return Advert
     */
    public function getAdvert()
    {
        return $this->advert;
    }

    /**
     * @param User $user
     * @return self
     */
    public function setUser(User $user)
    {
        $this->user = $user;
        $user->addBookMark($this);
        return $this;
    }

    /**
     * @return User
     */
    public function getUser()
    {
        return $this->user;
    }    
}

然后在您的User

/**
 * @ORM\OneToMany(targetEntity="Advert\Entity\BookMark", mappedBy="user", cascade={"remove"})
 */
 private $bookmarks;

/**
 * @return Collection
 */
public function getBookmarks() 
{
     return $this->bookmarks;
}

/**
 * @param BookMark $bookmark
 */
public function addBookmark(BookMark $bookmark)
{
   $this->bookmarks->add($bookmark);
}

/**
 * @param Collection $bookmarks
 */
public function addBookmarks(Collection $bookmarks)
{
   foreach ($bookmarks as $bookmark) {
       $this->addBookMark($bookmark);
   }
}

/**
 * @param BookMark $bookmark
 */
public function removeBookmark(BookMark $bookmark)
{
   $this->bookmarks->removeElement($bookmark);
}

/**
 * @param Collection $bookmarks
 */
public function removeBookmarks(Collection $bookmarks)
{
   foreach ($bookmarks as $bookmark) {
       $this->removeBookmark($bookmark);
   }
}

在您的Advert

/**
 * @ORM\OneToMany(targetEntity="Advert\Entity\BookMark", mappedBy="advert", cascade={"remove"})
 */
 private $bookmarks;

/**
 * @return Collection
 */
public function getBookmarks() 
{
     return $this->bookmarks;
}

/**
 * @param BookMark $bookmark
 */
public function addBookmark(BookMark $bookmark)
{
   $this->bookmarks->add($bookmark);
}

/**
 * @param Collection $bookmarks
 */
public function addBookmarks(Collection $bookmarks)
{
   foreach ($bookmarks as $bookmark) {
       $this->addBookMark($bookmark);
   }
}

/**
 * @param BookMark $bookmark
 */
public function removeBookmark(BookMark $bookmark)
{
   $this->bookmarks->removeElement($bookmark);
}

/**
 * @param Collection $bookmarks
 */
public function removeBookmarks(Collection $bookmarks)
{
   foreach ($bookmarks as $bookmark) {
       $this->removeBookmark($bookmark);
   }
}

為您服務:

/**
 * @param int $advertId
 */
public function saveAdvertBookmark($advertId)
{
    $entityManager = $this->getEntityManager():
    $user = $this->getUserEntity(); 

    $advert = $entityManager->find('Advert\Entity\Advert', $advertId):
    $bookmark = new \Advert\Entity\Bookmark();
    $bookmark->setUser($user);
    $bookmark->setAdvert($advert);

    $entityManager->persist($bookmark);
    $entityManager->flush();
}

要在刪除UserAdvert時刪除所有書簽,只需在這些實體中的書簽關系上添加cascade={"remove"}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM