我可以在不将实体连接到数据库表的情况下使用ORM

时间:2015-07-14 09:56:46

标签: entity-framework symfony orm doctrine-orm

我有一个实体从REST Web服务中提取数据。为了保持与我的应用程序中从数据库中提取数据的实体一致,我使用了ORM并覆盖了存储库中的查找函数。

我的问题是ORM似乎需要一个数据库表。当我运行doctrine:schema:update时,它抱怨需要实体的索引,然后当我添加一个索引时,它会为实体创建一个表。我想这将是一个问题,因为ORM将要查询数据库而不是Web服务。

所以......我做错了吗?

1,如果我继续使用ORM,我怎么能让它停止为单个实体需要数据库表。

2,如果我忘记了ORM我在哪里放置数据加载功能?我可以在不使用ORM的情况下将实体连接到存储库吗?

1 个答案:

答案 0 :(得分:0)

  

所以......我做错了吗?

是。如果您不想使用ORM,则使用ORM接口是没有意义的。

我认为最好的方法是根本不考虑实施细节。介绍您自己的存储库接口:

interface Products
{
    /**
     * @param string $slug
     *
     * @return Product[]
     */
    public function findBySlug($slug);
}

interface Orders
{
    /**
     * @param Product $product
     * 
     * @return Order[]
     */
    public function findProductOrders(Product $product);
}

用ORM实现它们:

class DoctrineProducts implements Products
{
    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function findBySlug($slug)
    {
        return $this->em->createQueryBuilder()
           ->select()
           // ...
    }
}

或休息客户:

class RestOrders implements Orders
{
    private $httpClient;

    public function __construct(HttpClient $httpClient)
    {
        $this->httpClient = $httpClient;
    }

    public function findProductOrders(Product $product)
    {
        $orders = $this->httpClient->get(sprintf('/product/%d/orders', $product->getId()));

        $orders = $this->hydrateResponseToOrdersInSomeWay($orders);

        return $orders;
    }
}

您甚至可以使某些方法使用http客户端,而某些方法则在单个存储库中使用该数据库。

将您的存储库注册为服务并使用它们,而不是直接调用Doctrine::getRepository()

services:
    repository.orders:
        class: DoctrineOrders
        arguments:
            - @doctrine.orm.entity_manager

始终依赖于您的存储库接口,而不是依赖于特定的实现。换句话说,始终使用存储库接口类型提示:

class DefaultController
{
    private $orders;

    public function __construct(Orders $orders)
    {
        $this->orders = $orders;
    }

    public function indexAction(Product $product)
    {
        $orders = $this->orders->findProductOrders($product);

        // ...
    }
}

如果您未将控制器注册为服务:

class DefaultController extends Controller
{
    public function indexAction(Product $product)
    {
        $orders = $this->get('repository.orders')->findProductOrders($product);

        // ...
    }
}

这种方法的一个巨大优势是您可以随时更改实施细节。 Mysql不再适合搜索了吗?我们使用弹性搜索,它只是一个存储库!

如果您需要在幕后调用$ product-> getOrders()并从API获取订单,那么仍然可以通过doctrine的延迟加载和事件监听器的帮助来实现。