如果我使用以下代码,Symfony2执行40个数据库查询的原因:
$em = $this->getDoctrine()->getManager();
$records = $em->getRepository('MyWebBundle:Highlight')->findAll();
我认为findAll()
方法只返回Highlight实体中的所有项目,而其他实体的关联则替换Proxy对象。但现在findAll()
方法获取所有关联实体。
你知道问题出在哪里吗?
的indexAction
public function indexAction() {
$em = $this->getDoctrine()->getManager();
$records = $em->getRepository('MyWebBundle:Highlight')->findAll();
$csrf = $this->get('security.csrf.token_manager');
$token = $csrf->refreshToken(self::FORM_TOKEN_ID);
$params = array(
"data" => array(
"all" => $records,
),
"token" => $token->getValue(),
"static" => array(
"add" => $this->generateUrl("admin_highlight_add"),
"edit" => $this->generateUrl("admin_highlight_edit"),
"del" => $this->generateUrl("admin_highlight_del"),
),
);
$ser = $this->get('jms_serializer');
$jsonContent = $ser->serialize($params, 'json');
return array('jsonContent' => $jsonContent);
}
突出显示实体
namespace My\WebBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
/**
* Highlight
*
* @JMS\ExclusionPolicy("none")
* @ORM\Table()
* @ORM\Entity(repositoryClass="My\WebBundle\Entity\HighlightRepository")
*/
class Highlight {
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="abbreviation", type="string", length=8, unique=true)
*/
private $abbreviation;
/**
* @var string
*
* @ORM\Column(name="description", type="string", length=80, nullable=true)
*/
private $description;
/**
* @var string
*
* @ORM\Column(name="color", type="string", length=7)
*/
private $color;
/**
* @var ArrayCollection
* @ORM\OneToMany(targetEntity="Goods", mappedBy="highlight")
*/
private $goods;
/**
* @var ArrayCollection
* @ORM\OneToMany(targetEntity="Calibration", mappedBy="highlight")
*/
private $calibrations;
/**
* Constructor
*/
public function __construct() {
$this->goods = new \Doctrine\Common\Collections\ArrayCollection();
$this->calibrations = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId() {
return $this->id;
}
/**
* Set abbreviation
*
* @param string $abbreviation
* @return Highlight
*/
public function setAbbreviation($abbreviation) {
$this->abbreviation = $abbreviation;
return $this;
}
/**
* Get abbreviation
*
* @return string
*/
public function getAbbreviation() {
return $this->abbreviation;
}
/**
* Set description
*
* @param string $description
* @return Highlight
*/
public function setDescription($description) {
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription() {
return $this->description;
}
/**
* Set color
*
* @param string $color
* @return Highlight
*/
public function setColor($color) {
$this->color = $color;
return $this;
}
/**
* Get color
*
* @return string
*/
public function getColor() {
return $this->color;
}
/**
* Add goods
*
* @param \My\WebBundle\Entity\Goods $goods
* @return Highlight
*/
public function addGood(\My\WebBundle\Entity\Goods $goods) {
$this->goods[] = $goods;
return $this;
}
/**
* Remove goods
*
* @param \My\WebBundle\Entity\Goods $goods
*/
public function removeGood(\My\WebBundle\Entity\Goods $goods) {
$this->goods->removeElement($goods);
}
/**
* Get goods
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getGoods() {
return $this->goods;
}
/**
* Add calibrations
*
* @param \My\WebBundle\Entity\Calibration $calibrations
* @return Highlight
*/
public function addCalibration(\My\WebBundle\Entity\Calibration $calibrations) {
$this->calibrations[] = $calibrations;
return $this;
}
/**
* Remove calibrations
*
* @param \My\WebBundle\Entity\Calibration $calibrations
*/
public function removeCalibration(\My\WebBundle\Entity\Calibration $calibrations) {
$this->calibrations->removeElement($calibrations);
}
/**
* Get calibrations
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCalibrations() {
return $this->calibrations;
}
}
突出显示存储库为空
答案 0 :(得分:2)
我认为问题来自序列化程序。由于你序列化了一个highliths,它们每个都有自己的属性序列化,这意味着将对已经序列化的已撤销商品执行延迟查询。
然后,您应该通过添加注释突出显示商品属性来阻止此行为
use ...
use JMS\SerializerBundle\Annotation\ExclusionPolicy;
use JMS\SerializerBundle\Annotation\Exclude;
/**
* ...
* @ExclusionPolicy("none")
*/
class Highlight
{
/**
* ...
* @Exclude
*/
private $goods;
}
获取有关排除任务的更多详细信息
答案 1 :(得分:0)
findAll本身不会执行很多查询。通过getter访问相关实体时执行查询。由于关系没有得到热切关注,所以当你进行关系时,他们会第一时间获取关系。
我认为序列化程序会访问所有子项以发送您的对象。
只要您有一个托管实体实例,就可以遍历 并使用配置为LAZY的该实体的任何关联,如果 他们已经在记忆中了。 Doctrine会自动加载 通过延迟加载的概念按需关联对象。
要防止这种情况,要么禁用子序列化,要么使用获取EAGER或构建DQL查询,该查询会预取所有子项以及父项,如(只是示例,无效DQL)
SELECT Highlight, Good, Calibration
FROM Highlights Highlight
LEFT JOIN Highlight.googs Good
LEFT JOIN Goog.calibrations Calibration
WHERE ...