在没有加入或新的 sql 请求的情况下获取实体子对象 ID
Get Entity subobject id without joining or new sql request
示例我有一个实体用户,它有一个联系人。如何在不加入联系人的情况下获取联系人 ID table.
$user = $entityManager->userRepository->findUserById(1);
$contactId = $user->getContact()->getId();
调用 `getContact() 时,将从数据库加载整个联系人。如何在不在 findUserById 中添加连接的情况下避免此 SQL 请求。我只需要我的用户 table 中的 contactId,但没有像 $user->getContactId() 这样的简单函数。
我建议您更改特定查询中的提取模式,如文档中here所述。
所以您可以如下描述您的查询:
// Supposing this method in the repository class
public function findUserById($idUser)
{
$qb = $this->createQueryBuilder('u')
->where("u.id = :idUser")
->setParameter("idUser", $idUser);
$query = $qb->getQuery();
// Describe here all the entity and the association name that you want to fetch eager
$query->setFetchMode("YourBundle\Entity\Contract", "contract", ClassMetadata::FETCH_EAGER);
...
return $qb->->getResult();
}
注意:
Changing the fetch mode during a query is only possible for one-to-one
and many-to-one relations.
希望对您有所帮助
看看这个postGetting only ID from entity relations without fetching whole object in Doctrine。我在 ManyToOne 关系中测试了一个简单示例,但未加载相关对象。
你的情况听起来很适合 Doctrine 二级缓存
有了这个,第一个查询将从数据库中获取,但每个后续查询都将来自二级缓存,另外,如果您使用 doctrine 更改数据,那么缓存会自动更新。因此,我建议您将缓存设置为很长的时间我个人最喜欢的是1个月约2592000秒。
像这样在您的用户实体中启用它
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
* @ORM\Cache(usage="NONSTRICT_READ_WRITE", region="users_region")
* @ORM\Table(
* name="site_users",
* indexes={
* @ORM\Index(name="username_index", columns={"username"}),
* @ORM\Index(name="email_index", columns={"email"}),
* @ORM\Index(name="enabled_index", columns={"enabled"}),
* @ORM\Index(name="last_login_index", columns={"last_login"})
* }
*)
*/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
......
然后在你的config.yml中这样
orm:
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
default:
connection: default
auto_mapping: true
naming_strategy: doctrine.orm.naming_strategy.underscore
second_level_cache:
enabled: true
# region_lock_lifetime: 60
region_lifetime: 300
log_enabled: %kernel.debug%
region_cache_driver: apc
regions:
users_region:
region_lifetime: 2592000
region_cache_driver: apc
.......
这里有更多信息
http://symfony.com/doc/master/bundles/DoctrineBundle/configuration.html
请注意,此方法还可确保对经过身份验证的用户 $user = $this->getUser();
的流行检查也不会命中您的数据库。
示例我有一个实体用户,它有一个联系人。如何在不加入联系人的情况下获取联系人 ID table.
$user = $entityManager->userRepository->findUserById(1);
$contactId = $user->getContact()->getId();
调用 `getContact() 时,将从数据库加载整个联系人。如何在不在 findUserById 中添加连接的情况下避免此 SQL 请求。我只需要我的用户 table 中的 contactId,但没有像 $user->getContactId() 这样的简单函数。
我建议您更改特定查询中的提取模式,如文档中here所述。
所以您可以如下描述您的查询:
// Supposing this method in the repository class
public function findUserById($idUser)
{
$qb = $this->createQueryBuilder('u')
->where("u.id = :idUser")
->setParameter("idUser", $idUser);
$query = $qb->getQuery();
// Describe here all the entity and the association name that you want to fetch eager
$query->setFetchMode("YourBundle\Entity\Contract", "contract", ClassMetadata::FETCH_EAGER);
...
return $qb->->getResult();
}
注意:
Changing the fetch mode during a query is only possible for one-to-one and many-to-one relations.
希望对您有所帮助
看看这个postGetting only ID from entity relations without fetching whole object in Doctrine。我在 ManyToOne 关系中测试了一个简单示例,但未加载相关对象。
你的情况听起来很适合 Doctrine 二级缓存
有了这个,第一个查询将从数据库中获取,但每个后续查询都将来自二级缓存,另外,如果您使用 doctrine 更改数据,那么缓存会自动更新。因此,我建议您将缓存设置为很长的时间我个人最喜欢的是1个月约2592000秒。
像这样在您的用户实体中启用它
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
* @ORM\Cache(usage="NONSTRICT_READ_WRITE", region="users_region")
* @ORM\Table(
* name="site_users",
* indexes={
* @ORM\Index(name="username_index", columns={"username"}),
* @ORM\Index(name="email_index", columns={"email"}),
* @ORM\Index(name="enabled_index", columns={"enabled"}),
* @ORM\Index(name="last_login_index", columns={"last_login"})
* }
*)
*/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
......
然后在你的config.yml中这样
orm:
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
default:
connection: default
auto_mapping: true
naming_strategy: doctrine.orm.naming_strategy.underscore
second_level_cache:
enabled: true
# region_lock_lifetime: 60
region_lifetime: 300
log_enabled: %kernel.debug%
region_cache_driver: apc
regions:
users_region:
region_lifetime: 2592000
region_cache_driver: apc
.......
这里有更多信息
http://symfony.com/doc/master/bundles/DoctrineBundle/configuration.html
请注意,此方法还可确保对经过身份验证的用户 $user = $this->getUser();
的流行检查也不会命中您的数据库。