PHP(Symfony2)数组:" INNER JOIN"

时间:2014-04-02 10:48:59

标签: php arrays entity-framework symfony dql

我有一个问题,我需要根据各种实体属性过滤实体。其中一些属性链接到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;
    }
}

1 个答案:

答案 0 :(得分:1)

以下是如何实现这一目标的快速示例。假设您有BookRepositoryBookFilterType,它定义了用户可以使用的过滤器类型:

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方法在引擎盖下处理的。