想象一下,我有两个ORM实体:
作者实体:
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(
* name="authors",
* uniqueConstraints={@ORM\UniqueConstraint(name="date", columns={"author_id"})}
* )
*/
class Author implements \JsonSerializable
{
/**
* @var integer
*
* @ORM\Column(type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
public $id;
/**
* @var string
* @ORM\Column(type="string", length=250, nullable=true)
*/
public $name;
/**
*
* Many Authors have Many Books.
* @ORM\ManyToMany(targetEntity="Book")
* @ORM\JoinTable(name="authors_books",
* joinColumns={@ORM\JoinColumn(name="author_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="book_id", referencedColumnName="id")}
* )
*/
public $books;
public function __construct(User $user, \DateTime $startDate, \DateTime $ringDate, $phone, $name, $direction, $duration, $comment, $phoneId, $appVersion)
{
$this->name = $name;
$this->books = new \Doctrine\Common\Collections\ArrayCollection();
}
public function jsonSerialize()
{
return [
'id' => $this->id,
'name' => $this->name,
'books' => $this->books,
];
}
}
图书实体:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="books")
* @ORM\Entity()
*/
class Book implements \JsonSerializable
{
/**
* @var integer
*
* @ORM\Column(type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
public $id;
/**
* @var string
* @ORM\Column(type="string", length=120, nullable=false)
*/
public $description;
/**
* @var string
* @ORM\Column(type="string", length=10)
*/
public $color;
public function __construct($decription)
{
$this->$decription = $decription;
}
public function getId()
{
return $this->id;
}
public function getdecription()
{
return $this->decription;
}
public function setDecription($decription)
{
$this->decription = $decription;
}
function jsonSerialize()
{
return [
'id' => $this->id,
'decription' => $this->decription,
];
}
}
作为此关系的结果,生成authors_books表。
我现在的目标是设计一个控制器,它将返回以下json format
示例中的作者列表:
{
authors: [
{
name: "Oscar Wilde",
books : [
{
id: 1,
description: "The Picture of Dorian Gray"
},
{
id: 2,
description: "The Happy Prince and Other Tales"
}
]
},
{
name: "Charles Dickens",
books : [
{
id: 3,
description: "Great Expectations"
},
{
id: 4,
description: "Oliver Twist"
}
]
}
]
}
使用这样的休息控制器:
/**
* @Route("/my/v1", service="app.authors_controller")
*/
class MyController extends BaseApiController
{
/**
* @Route("/authors", name="my_v1_authors")
* @Method("GET")
*/
public function authors(Request $request)
{
$qb = $this->authorRepository->createQueryBuilder('c');
return new JsonResponse(array(
'authors' => ...
));
}
}
至于现在,我有两个实现这个目标的想法:
但他们两个在我看来有点hacky。我该怎么办?
请注意,这是我想要实现的简化表示。虽然对于这个特定的例子采用多对多关系似乎是一个开销,但对我当前的任务至关重要。
答案 0 :(得分:1)
如何更改作者实体中的JsonSerialize
public function jsonSerialize()
{
$author = [
'id' => $this->id,
'name' => $this->name,
'books' => []
];
foreach($this->books as $book)
{
$author['books'][] = $book->jsonSerialize();
}
return $author;
}
并在您的控制器中:
$authors = /** your optimized query here **/
$serializedAuthors = [];
foreach($authors as $author)
{
$serializedAuthors[] = $author->jsonSerialize();
}
如果您可以重复使用此逻辑,可以考虑使用symfony中的Serializer组件,可以在此处找到一个很棒的指南https://thomas.jarrand.fr/blog/serialization/
或者也许使用JMSSerializer。
修改强>
您的DQL可能如下所示:
$authors = $this->getEntityManager()->createQuery('
SELECT author, books
FROM AppBundle\Entity\Author author
JOIN author.books books
')->getResult();