如何创建自定义Repository类

3.4 版本
维护中的版本

上一篇中,你已经开始在controller中构建和使用复杂的查询了。为了隔离,重用和测试这些查询,一个好的办法是为你的实体创建一个自定义的repository类并添加相关逻辑查询方法。

要定义repository类,首先需要在你的映射定义中添加repository类的声明:

1
2
3
4
5
6
7
8
9
10
11
12
// src/AppBundle/Entity/Product.php
namespace AppBundle\Entity;
 
use Doctrine\ORM\Mapping as ORM;
 
/**
 * @ORM\Entity(repositoryClass="AppBundle\Entity\ProductRepository")
 */
class Product
{
    //...
}
1
2
3
4
5
# src/AppBundle/Resources/config/doctrine/Product.orm.yml
AppBundle\Entity\Product:
    type: entity
    repositoryClass: AppBundle\Entity\ProductRepository
    # ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- src/AppBundle/Resources/config/doctrine/Product.orm.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
        http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
 
    <entity
        name="AppBundle\Entity\Product"
        repository-class="AppBundle\Entity\ProductRepository">
 
        <!-- ... -->
    </entity>
</doctrine-mapping>

然后通过运行跟之前生成丢失的getter和setter方法同样的命令行,Doctrine会为你自动生成repository类。

$ php bin/console doctrine:generate:entities AppBundle

如果你选择自己创建repository类,你要继承Doctrine\ORM\EntityRepository

下面,添加一个新方法findAllOrderedByName() 到新生成的ProductRepository类。该方法将查询所有的Product实体,并按照name的字符顺序排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// src/AppBundle/Entity/ProductRepository.php
namespace AppBundle\Entity;
 
use Doctrine\ORM\EntityRepository;
 
class ProductRepository extends EntityRepository
{
    public function findAllOrderedByName()
    {
        return $this->getEntityManager()
            ->createQuery(
                'SELECT p FROM AppBundle:Product p ORDER BY p.name ASC'
            )
            ->getResult();
    }
}

在Repository类中可以通过$this->getEntityManager()方法类获取entity管理。

你就可以像使用默认的方法一样使用这个新定义的方法了:

1
2
3
$em = $this->getDoctrine()->getManager();
$products = $em->getRepository('AppBundle:Product')
    ->findAllOrderedByName();

当使用一个自定义的repository类时,你依然可以访问原有的默认查找方法,比如find()findAll()等。

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)