在没有加入或新的 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 二级缓存

http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/second-level-cache.html

有了这个,第一个查询将从数据库中获取,但每个后续查询都将来自二级缓存,另外,如果您使用 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(); 的流行检查也不会命中您的数据库。