Symfony/学说

Posted

技术标签:

【中文标题】Symfony/学说【英文标题】:Symfony/Doctrine 【发布时间】:2012-06-11 18:34:56 【问题描述】:

我目前正在通过reading the docs 学习 Symfony 和 Doctrine。

我不明白 findfindOneById 之间的区别。我尝试在这个简单的示例中同时使用它们,看起来它们对我做了同样的事情。

$product = $this->getDoctrine()
                ->getRepository('AcmeStoreBundle:ProductEntity')
                ->findOneById($id);

它们真的是一回事还是有一些不同?在哪里可以找到所有这些方法的详细文档?

【问题讨论】:

【参考方案1】:
// query by the primary key (usually "id")
$product = $repository->find($id);

// dynamic method names to find based on a column value
$product = $repository->findOneById($id);
// $foo is any name which you want to find from database
$product = $repository->findOneByName($foo);

【讨论】:

【参考方案2】:

是一样的东西,但我更喜欢findOneBy方法。更清楚了。

【讨论】:

【参考方案3】:

它最终调用了相同的方法。

findByKey('value')

基本一样

findBy(array('key' => 'value'))

其中key是实体的属性,value是属性的值。

findById($id)

是上述情况的一个特例。

find($id)

所有这些方法最终都执行相同的查询。不过还是有区别的

findBy()

findOneBy()

其中 findOneBy() 只返回一个结果,而 findBy 将返回所有满足需求的结果。

但是,一般来说,使用 DQL 查询是一种很好的做法。考虑延迟加载、数组水合、准备好的语句等。 这是一篇关于该主题的有趣文章: Some Doctrine 2 Best Practices

【讨论】:

【参考方案4】:

其实不是一回事。

考虑一下。如果您调用“findBy()”,您假设您将收到一组实体(0、1 或多个)。因此,要获得所有结果,您需要迭代 ArrayCollection 或仅获得第一个( $result->first() )。

如果您的查询是通过唯一键(如本例),您可以通过调用“getOneById()”获取唯一实体,您将收到该实体作为结果。

/**
 * Retrieving Product with 'findOneBy'
 */
$product = $this->getDoctrine()
                ->getRepository('AcmeStoreBundle:ProductEntity')
                ->findOneById($id);

/**
 * Retrieving Product with 'findBy'
 */
$product = $this->getDoctrine()
                ->getRepository('AcmeStoreBundle:ProductEntity')
                ->findById($id)
                ->first();

从语义上讲,第一个是最好的。

*提示

实体应该被称为产品。 为什么?因为在“/Entity”文件夹下(Almost, should...),并且命名空间将包含有关“什么是产品”的信息

【讨论】:

【参考方案5】:

有一个APIhere我认为没有什么区别:这两个方法,当调用你调用它们的方式时,这样做:

return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id);

但是在某些情况下 find 会越来越快,因为它不使用 __call 魔术方法,并且因为 find() 之前检查当前工作单元的映射,而 load() 没有(见@todo):

/**                                                                         
 * Loads an entity by a list of field criteria.                             
 * ...
 * 
 * @todo Check identity map? loadById method? Try to guess whether $criteria is the id?
 */                                                                         
public function load(array $criteria, $entity = null, $assoc = null, array $hints = array(), $lockMode = 0) 

所以更喜欢find()findOneById() 只是做同样事情的效率较低的方法。

【讨论】:

【参考方案6】:

在你的情况下,他们碰巧做同样的事情。查看this example,您会注意到find() 查找以主键命名的字段。 findOneBy<Field>() 将显式使用方法名称中的字段,即使它不是主键,也会返回第一条记录。所以,最后,如果主键确实命名为id,那么两者都会做同样的事情。

// query by the primary key (usually "id")
$product = $repository->find($id);

// dynamic method names to find based on a column value
$product = $repository->findOneById($id);
$product = $repository->findOneByName('foo');

【讨论】:

谢谢,我不明白这是一个动态方法名,所以我很难找到它。 我想补充一点,find() 按主键查找实体,主键可能包含多个列(复合键)。 find() 通过传递像 array('column1' => $value1, 'column2' => $value2) 这样的数组来支持这一点。

以上是关于Symfony/学说的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 学说清除缓存

symfony 3 学说不接受主键

Symfony2,学说和数据域

Symfony - 在服务中注入学说存储库

学说查询的语法错误 (Symfony2)

Symfony 4.3 学说迁移问题