使用 QueryBuilder 时停止在doctrine2中查询相关实体
我有两个具有一对一关系的实体用户和配置文件。
$qb = $this->getDoctrine()->getEntityManager()->createQueryBuilder();
$qb->add('select', 'u')
->add('from', '\Acme\TestBundle\Entity\User u')
->add('orderBy', 'u.id DESC');
$query = $qb->getQuery();
$customer = $query->execute();
当我检查 Symfony Profiler 中的查询数量时,我可以看到在用户表中的 n 个用户的配置文件表上触发的查询数量。有什么办法可以停止查询配置文件表。
如果有更好的实现方法,请告诉我。
预先感谢
添加实体类
class User
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $email
*
* @ORM\Column(name="email", type="string", length=255)
*/
private $email;
/**
* @var Acme\TestBundle\Entity\Profile
*
* @ORM\OneToOne(targetEntity="Acme\TestBundle\Entity\Profile", mappedBy="user")
*/
private $profile;
}
class Profile
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var integer $user_id
*
* @ORM\Column(name="user_id", type="integer")
*/
private $user_id;
/**
* @var string $user_name
*
* @ORM\Column(name="user_name", type="string", length=100)
*/
private $user_name;
/**
* @var Acme\TestBundle\Entity\User
*
* @ORM\OneToOne(targetEntity="Acme\TestBundle\Entity\User", inversedBy="profile")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
}
mysql日志的响应
120110 15:14:29 89 Connect root@localhost on test
89 Query SET NAMES UTF8
89 Query SELECT c0_.id AS id0, c0_.email AS email1, c0_.password AS password2, c0_.is_demo_user AS is_demo_user3, c0_.status AS status4, c0_.current_service AS current_service5, c0_.registration_mode AS registration_mode6, c0_.verification_code AS verification_code7, c0_.account_type AS account_type8, c0_.activated_date AS activated_date9, c0_.status_updated_at AS status_updated_at10, c0_.created_at AS created_at11, c0_.updated_at AS updated_at12 FROM user c0_ WHERE c0_.id = 1 ORDER BY c0_.email ASC
89 Query SELECT t0.id AS id1, t0.user_id AS user_id2, t0.user_name AS user_name3, t0.age AS age4, t0.created_at AS created_at5, t0.updated_at AS updated_at6, t0.user_id AS user_id7 FROM profile t0 WHERE t0.user_id = '1'
89 Quit
I am having two entities User and Profile with one to one relationship.
$qb = $this->getDoctrine()->getEntityManager()->createQueryBuilder();
$qb->add('select', 'u')
->add('from', '\Acme\TestBundle\Entity\User u')
->add('orderBy', 'u.id DESC');
$query = $qb->getQuery();
$customer = $query->execute();
When i Check the number of queries in Symfony profiler I could see n number for queries triggered on Profile table for n users in User table. Is there any way where I can stop the querying of the Profile table.
Please let me know if there is better way of implementing it.
Thanks in advance
Added Entity Classes
class User
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $email
*
* @ORM\Column(name="email", type="string", length=255)
*/
private $email;
/**
* @var Acme\TestBundle\Entity\Profile
*
* @ORM\OneToOne(targetEntity="Acme\TestBundle\Entity\Profile", mappedBy="user")
*/
private $profile;
}
class Profile
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var integer $user_id
*
* @ORM\Column(name="user_id", type="integer")
*/
private $user_id;
/**
* @var string $user_name
*
* @ORM\Column(name="user_name", type="string", length=100)
*/
private $user_name;
/**
* @var Acme\TestBundle\Entity\User
*
* @ORM\OneToOne(targetEntity="Acme\TestBundle\Entity\User", inversedBy="profile")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
}
Response from the mysql log
120110 15:14:29 89 Connect root@localhost on test
89 Query SET NAMES UTF8
89 Query SELECT c0_.id AS id0, c0_.email AS email1, c0_.password AS password2, c0_.is_demo_user AS is_demo_user3, c0_.status AS status4, c0_.current_service AS current_service5, c0_.registration_mode AS registration_mode6, c0_.verification_code AS verification_code7, c0_.account_type AS account_type8, c0_.activated_date AS activated_date9, c0_.status_updated_at AS status_updated_at10, c0_.created_at AS created_at11, c0_.updated_at AS updated_at12 FROM user c0_ WHERE c0_.id = 1 ORDER BY c0_.email ASC
89 Query SELECT t0.id AS id1, t0.user_id AS user_id2, t0.user_name AS user_name3, t0.age AS age4, t0.created_at AS created_at5, t0.updated_at AS updated_at6, t0.user_id AS user_id7 FROM profile t0 WHERE t0.user_id = '1'
89 Quit
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的答案就在这里!!
http://docs.doctrine -project.org/projects/doctrine-orm/en/latest/tutorials/extra-lazy-associations.html
“在许多情况下,实体之间的关联可能会变得相当大。即使在简单的情况下,在像博客这样的场景中,您总是必须假设一个帖子会吸引数百条评论,如果您访问一个关联,它总是会完全加载到内存中,这可能会导致非常严重的性能问题。如果您的关联包含数百或数千个实体,则
在 Doctrine 2.1 中为关联引入了一个名为“Extra Lazy”的功能,默认情况下,关联将被标记为“Lazy”,这意味着关联的整个集合对象都被标记为“Lazy”。如果您将关联标记为额外惰性,则可以在不触发集合的完全加载的情况下调用集合上的以下方法:“
有点晚了,但它可能会对其他人有所帮助!
Your answer is here!!
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/extra-lazy-associations.html
"In many cases associations between entities can get pretty large. Even in a simple scenario like a blog. where posts can be commented, you always have to assume that a post draws hundrets of comments. In Doctrine 2.0 if you accessed an association it would always get loaded completly into memory. This can lead to pretty serious performance problems, if your associations contain several hundrets or thousands of entities.
With Doctrine 2.1 a feature called Extra Lazy is introduced for associations. Associations are marked as Lazy by default, which means the whole collection object for an association is populated the first time its accessed. If you mark an association as extra lazy the following methods on collections can be called without triggering a full load of the collection:"
It's a bit late, but it might help others out there!