Symfony/学说
Posted
技术标签:
【中文标题】Symfony/学说【英文标题】:Symfony/Doctrine 【发布时间】:2012-06-11 18:34:56 【问题描述】:我目前正在通过reading the docs 学习 Symfony 和 Doctrine。
我不明白 find 和 findOneById 之间的区别。我尝试在这个简单的示例中同时使用它们,看起来它们对我做了同样的事情。
$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/学说的主要内容,如果未能解决你的问题,请参考以下文章