[英]Doctrine2 ORM Access ManyToMany Join Table
我先前問題的跟進
我接受了給出的非常有幫助的答案,因為它為我指明了正確的方向。 不幸的是,我很難使其余的工作正常進行,但是由於問題時間太長且令人困惑,所以我提出了一個新問題。
我有一個頁面,用戶可以在其中寫廣告。 用戶還可以在他們希望在其用戶部分中看到的廣告添加書簽。
我有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
。 這兩個組合創建了一個復合密鑰。
因此,從User
到Bookmark
的關系是一對多的。 並添加書簽給用戶多對一。
從Advert
到Bookmark
的關系是一對多的,從Bookmark
到Advert
的關系是多對一的。
您的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();
}
要在刪除User
或Advert
時刪除所有書簽,只需在這些實體中的書簽關系上添加cascade={"remove"}
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.