我有一个问题,我需要根据各种实体属性过滤实体。其中一些属性链接到ManyToOne或ManyToMany关系中的其他实体。我在Symfony2工作,并且得出的结论是,动态编写单个DQL查询以仅按所选属性进行过滤对于我的经验水平而言过于复杂,所以我想要做的是为每个过滤器属性检索结果集数组然后合并它们,但是这样只有BOTH数组A和数组B中存在的数组项才会出现在我的结果数组中。我一直试图找到一些容易让我这样做的东西,但我一直找不到任何东西。
如果任何Symfony2开发人员看到这个线程,我意识到以上述方式执行它并不理想,所以如果你能帮我创建一个可以做到这一点的DQL查询,我将非常感激。以下是我需要过滤结果的实体。我需要过滤的属性是"类别","作者","流派"和"语言"。假设我从REQUEST中提取一个类似于array('category' => 1, 'genre' => 6, 'author' => 8, 'language' => 2);
的数组,其中至少有一个必须存在,但并非所有数组都必须存在。
<?php
namespace Pmb\LicensingBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use JMS\Serializer\Annotation as Ser;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* Ebook
*
* @ORM\Entity
* @ORM\Table(name="ebooks")
* @Ser\ExclusionPolicy("all")
*/
class Ebook
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @Ser\Expose
*/
private $id;
/**
* @var Category[]
*
* @ORM\ManyToMany(targetEntity="Pmb\LicensingBundle\Entity\Category", inversedBy="ebooks", cascade={"remove"})
* @ORM\OrderBy({"name" = "ASC"})
**/
private $categories;
/**
* @var Author[]
*
* @ORM\ManyToMany(targetEntity="Pmb\LicensingBundle\Entity\Author", inversedBy="ebooks", cascade={"remove"})
* @ORM\OrderBy({"lastname" = "ASC", "firstnames" = "ASC"})
* @Ser\Expose
**/
private $authors;
/**
* @var Curriculum
*
* @ORM\ManyToOne(targetEntity="Pmb\LicensingBundle\Entity\Curriculum", inversedBy="ebooks", cascade={"remove"})
* @ORM\OrderBy({"name" = "ASC"})
* @Ser\Expose
**/
private $curriculum;
/**
* @var Genre
*
* @ORM\ManyToOne(targetEntity="Pmb\LicensingBundle\Entity\Genre", inversedBy="ebooks", cascade={"remove"})
* @ORM\OrderBy({"description" = "ASC"})
* @Ser\Expose
**/
private $genre;
/**
* @var Language
*
* @ORM\ManyToOne(targetEntity="Pmb\LicensingBundle\Entity\Language", inversedBy="ebooks", cascade={"remove"})
* @Ser\Expose
**/
private $language;
/**
* @var string
*
* @ORM\Column(name="isbn", type="string", length=16, unique=true)
* @Ser\Expose
* @Assert\Length(min=4, max=16)
*/
private $isbn;
/**
* @var string
*
* @ORM\Column(name="stock_code", type="string", length=16)
* @Ser\Expose
* @Assert\Length(min=4, max=16)
*/
private $stockCode;
/**
* @var string
*
* @ORM\Column(name="grade", type="integer", nullable=true)
* @Ser\Expose
* @Assert\Type({"int"})
*/
private $grade;
/**
* @var string
*
* @ORM\Column(name="price", type="float")
* @Ser\Expose
* @Assert\Type({"float"})
*/
private $price;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=128)
* @Ser\Expose
* @Assert\Length(min=3, max=128)
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="description", type="string", length=255, nullable=true)
* @Ser\Expose
* @Assert\Length(max=255)
*/
private $description;
/**
* @var \DateTime
*
* @ORM\Column(name="year_of_pub", type="datetime", nullable=true)
* @Ser\Expose
* @Assert\DateTime
*/
private $yearOfPub;
/**
* @var string
*
* @ORM\Column(name="ebook_file", type="string", length=256, nullable=true)
* @Ser\Expose
*/
private $ebookFile;
/**
* @var string
*
* @ORM\Column(name="thumbnail", type="string", length=256, nullable=true)
* @Ser\Expose
*/
private $thumbnail;
/**
* @var \DateTime
*
* @ORM\Column(name="date_created", type="datetime")
* @Ser\Expose
* @Assert\DateTime
*/
private $dateCreated;
/**
* @var boolean
*
* @ORM\Column(name="active", type="boolean")
* @Ser\Expose
*/
private $active;
/**
* @var boolean
*
* @ORM\Column(name="allow_trial", type="boolean")
* @Ser\Expose
*/
private $allowTrial;
/**
* @var boolean
*
* @ORM\Column(name="featured", type="boolean")
* @Ser\Expose
*/
private $featured;
//////////////////////////////////////////////////////////////////////////////////////
// METHODS
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
// GETTERS AND SETTERS
//////////////////////////////////////////////////////////////////////////////////////
/**
* Constructor
*/
public function __construct()
{
$this->categories = new \Doctrine\Common\Collections\ArrayCollection();
$this->authors = new \Doctrine\Common\Collections\ArrayCollection();
$this->curriculums = new \Doctrine\Common\Collections\ArrayCollection();
$this->genres = new \Doctrine\Common\Collections\ArrayCollection();
$this->active = true;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set isbn
*
* @param string $isbn
* @return Ebook
*/
public function setIsbn($isbn)
{
$this->isbn = $isbn;
return $this;
}
/**
* Get isbn
*
* @return string
*/
public function getIsbn()
{
return $this->isbn;
}
/**
* Set stockCode
*
* @param string $stockCode
* @return Ebook
*/
public function setStockCode($stockCode)
{
$this->stockCode = $stockCode;
return $this;
}
/**
* Get stockCode
*
* @return string
*/
public function getStockCode()
{
return $this->stockCode;
}
/**
* Set grade
*
* @param integer $grade
* @return Ebook
*/
public function setGrade($grade)
{
$this->grade = $grade;
return $this;
}
/**
* Get grade
*
* @return integer
*/
public function getGrade()
{
return $this->grade;
}
/**
* Set price
*
* @param float $price
* @return Ebook
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* @return float
*/
public function getPrice()
{
return $this->price;
}
/**
* Set name
*
* @param string $name
* @return Ebook
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* @param string $description
* @return Ebook
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set yearOfPub
*
* @param \DateTime $yearOfPub
* @return Ebook
*/
public function setYearOfPub($yearOfPub)
{
$this->yearOfPub = $yearOfPub;
return $this;
}
/**
* Get yearOfPub
*
* @return \DateTime
*/
public function getYearOfPub()
{
return $this->yearOfPub;
}
/**
* Set active
*
* @param boolean $active
* @return Ebook
*/
public function setActive($active)
{
$this->active = $active;
return $this;
}
/**
* Get active
*
* @return boolean
*/
public function getActive()
{
return $this->active;
}
/**
* Add categories
*
* @param \Pmb\LicensingBundle\Entity\Category $categories
* @return Ebook
*/
public function addCategory(\Pmb\LicensingBundle\Entity\Category $categories)
{
$this->categories[] = $categories;
return $this;
}
/**
* Remove categories
*
* @param \Pmb\LicensingBundle\Entity\Category $categories
*/
public function removeCategory(\Pmb\LicensingBundle\Entity\Category $categories)
{
$this->categories->removeElement($categories);
}
/**
* Get categories
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCategories()
{
return $this->categories;
}
/**
* Add authors
*
* @param \Pmb\LicensingBundle\Entity\Author $authors
* @return Ebook
*/
public function addAuthor(\Pmb\LicensingBundle\Entity\Author $authors)
{
$this->authors[] = $authors;
return $this;
}
/**
* Remove authors
*
* @param \Pmb\LicensingBundle\Entity\Author $authors
*/
public function removeAuthor(\Pmb\LicensingBundle\Entity\Author $authors)
{
$this->authors->removeElement($authors);
}
/**
* Get authors
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getAuthors()
{
return $this->authors;
}
/**
* Set language
*
* @param \Pmb\LicensingBundle\Entity\Language $language
* @return Ebook
*/
public function setLanguage(\Pmb\LicensingBundle\Entity\Language $language = null)
{
$this->language = $language;
return $this;
}
/**
* Get language
*
* @return \Pmb\LicensingBundle\Entity\Language
*/
public function getLanguage()
{
return $this->language;
}
/**
* Set allowTrial
*
* @param boolean $allowTrial
* @return Ebook
*/
public function setAllowTrial($allowTrial)
{
$this->allowTrial = $allowTrial;
return $this;
}
/**
* Get allowTrial
*
* @return boolean
*/
public function getAllowTrial()
{
return $this->allowTrial;
}
/**
* Set dateCreated
*
* @param \DateTime $dateCreated
* @return Ebook
*/
public function setDateCreated($dateCreated)
{
$this->dateCreated = $dateCreated;
return $this;
}
/**
* Get dateCreated
*
* @return \DateTime
*/
public function getDateCreated()
{
return $this->dateCreated;
}
/**
* Set featured
*
* @param boolean $featured
* @return Ebook
*/
public function setFeatured($featured)
{
$this->featured = $featured;
return $this;
}
/**
* Get featured
*
* @return boolean
*/
public function getFeatured()
{
return $this->featured;
}
/**
* Add categories
*
* @param \Pmb\LicensingBundle\Entity\Category $categories
* @return Ebook
*/
public function addCategorie(\Pmb\LicensingBundle\Entity\Category $categories)
{
$this->categories[] = $categories;
return $this;
}
/**
* Remove categories
*
* @param \Pmb\LicensingBundle\Entity\Category $categories
*/
public function removeCategorie(\Pmb\LicensingBundle\Entity\Category $categories)
{
$this->categories->removeElement($categories);
}
/**
* Set curriculum
*
* @param \Pmb\LicensingBundle\Entity\Curriculum $curriculum
* @return Ebook
*/
public function setCurriculum(\Pmb\LicensingBundle\Entity\Curriculum $curriculum = null)
{
$this->curriculum = $curriculum;
return $this;
}
/**
* Get curriculum
*
* @return \Pmb\LicensingBundle\Entity\Curriculum
*/
public function getCurriculum()
{
return $this->curriculum;
}
/**
* Set genre
*
* @param \Pmb\LicensingBundle\Entity\Genre $genre
* @return Ebook
*/
public function setGenre(\Pmb\LicensingBundle\Entity\Genre $genre = null)
{
$this->genre = $genre;
return $this;
}
/**
* Get genre
*
* @return \Pmb\LicensingBundle\Entity\Genre
*/
public function getGenre()
{
return $this->genre;
}
/**
* Set ebookFile
*
* @param string $ebookFile
* @return Ebook
*/
public function setEbookFile($ebookFile)
{
$this->ebookFile = $ebookFile;
return $this;
}
/**
* Get ebookFile
*
* @return string
*/
public function getEbookFile()
{
return $this->ebookFile;
}
/**
* Set thumbnail
*
* @param string $thumbnail
* @return Ebook
*/
public function setThumbnail($thumbnail)
{
$this->thumbnail = $thumbnail;
return $this;
}
/**
* Get thumbnail
*
* @return string
*/
public function getThumbnail()
{
return $this->thumbnail;
}
}
答案 0 :(得分:1)
以下是如何实现这一目标的快速示例。假设您有BookRepository
和BookFilterType
,它定义了用户可以使用的过滤器类型:
class BookRepository extends EntityRepository
{
protected $queryBuilder;
public function filterByGenre($genre)
{
return $this->getQueryBuilder()
->andWhere("b.genre = :genre")
->setParameter('genre', $genre);
}
public function filterByWhatever($whatever)
{
return $this->getQueryBuilder()
->andWhere("b.whatever = :whatever")
->setParameter('whatever', $whatever);
}
public function getFilterResult()
{
$result = $this->getQueryBuilder()
->getQuery->getResult();
$this->queryBuilder = null;
return $result;
}
public function getQueryBuilder()
{
if(!$this->queryBuilder)
$this->queryBuilder = $this->createQueryBuilder("b");
return $this->queryBuilder;
}
}
在您的控制器中:
public function indexAction(Request $request)
{
$form = $this->createForm(new BookFilterType());
if($request->isMethod("POST"))
{
$form->submit($request);
if($form->isValid())
{
$filters = $form->getData();
// pass filters to the repository
$books = $bookRepository
->filterByGenre($filters['genre'])
->filterByWhatever($filters['whatever'])
->getFilterResult();
return ['books' => $books]; // render filtered books in template
}
}
}
您还可以使用GET表单(通过URL传递过滤器);这无关紧要,因为它是由bind
方法在引擎盖下处理的。