gpt4 book ai didi

php - 在 Symfony2 中组织可重用 DBAL 查询的最佳实践?

转载 作者:可可西里 更新时间:2023-11-01 12:32:59 25 4
gpt4 key购买 nike

我目前正在做一个 Symfony2 项目。在大多数情况下,它是完全标准的;我正在使用 ORM 层通过我的实体与数据库交互。那里没有问题。

但是,我确实需要对系统中其他地方的现有模式中的一小部分表进行不频繁的查询,其中包含我称之为“引用”信息的内容:货币兑换率等。我只有 SELECT 访问此架构。

我建立了另一个连接,我一直在下降到 DBAL 层以对该模式进行查询,到目前为止它运行良好。

我的问题是,虽然不常见,但我认为我需要在我的应用程序的多个位置重复我的一些 DBAL 查询;我想将这些查询重构到某种存储库中,在那里它们更容易使用/测试/等等。我考虑过为表创建实体,但我觉得在这种情况下这太过分了。我认为您需要实体来创建存储库是否正确?

相反,我想知道是否有“Symfony 方式”来做到这一点?漂亮而优雅的东西:)

谢谢!达拉赫

最佳答案

更新

2013-10-03

请原谅我编辑了一个两年前的答案......然而,有几个人质疑现有的方法,虽然它有效(并且对我的特定用例有效),但定义服务当然是 Symfony 方式

没有人提供示例,因此为了引用/完整性,我将更新我的答案。我不得不承认,当我最初发布此答案时,我并不是真的au fait定义自定义服务,但我们生活和学习。

下面保留原答案。

1。创建额外的 DBAL 连接

  • app/config/config.yml 中创建连接 foo
  • 在这种情况下不需要参数 wrapper_class(请参阅原始答案)。
doctrine:
dbal:
connections:
default:
driver: %database_driver%
host: %database_host%
dbname: %database_name%
user: %database_user%
foo:
driver: %foo_driver%
host: %foo_host%
dbname: %foo_name%
user: %foo_user%

2。配置服务

  • 采用 YAML 格式。
  • 将配置添加到 src/Acme/TestBundle/Resources/config/services.yml
  • 请注意,我们将上面定义的 DBAL foo_connection 注入(inject)到服务中。
services:
foo_query_service:
class: Acme\TestBundle\Services\FooQueryService
arguments:
- @doctrine.dbal.foo_connection

3。为配置的服务创建类

  • src/Acme/TestBundle/Services/FooQueryService.php 中创建以下类:
<?php

namespace Acme\TestBundle\Services;

use DateTime;
use Doctrine\DBAL\Connection;

class FooQueryService
{
private $connection;

public function __construct(Connection $connection)
{
$this->connection = $connection;
}

public function findBarByDate(DateTime $date)
{
$stmt = $this->connection->prepare('SELECT * FROM bar WHERE date = :date');
$stmt->bindValue('date', $date, 'datetime');
$stmt->execute();

return $stmt->fetch();
}
}

4。最后,在任何需要的地方使用您的查询!

例如,在 Controller 中...

/**
* @Route("/", name="home")
* @Template()
*/
public function indexAction()
{
$date = new \DateTime();

$result = $this->get('foo_query_service')
->findBarByDate($date);

return array();
}

完成 :) 感谢 Acayrakoskoz 的反馈。


好的,我想我找到了适合我的解决方案。

实际上,我又重新审视了创建实体/管理器——实际上似乎缺少有关将特定实体映射到多个管理器的 Symfony2 文档。在这种情况下,这似乎仍然是一种矫枉过正的方法(而且“引用”模式非常困惑)。

幸运的是,可以为 DBAL 连接指定一个包装器类,并将查询抽象到那里的特定方法中。

  1. 使用 config.yml 中的包装器类创建额外的 DBAL 连接:
doctrine:
orm:
connections:
default:
driver: %driver%
host: %host%
dbname: %name%
user: %user%
foo:
wrapper_class: 'Acme\TestBundle\Doctrine\DBAL\FooConnection'
driver: %foo_driver%
host: %foo_host%
dbname: %foo_name%
user: %foo_user%
  1. 在指定路径创建包装类:
<?php

namespace Acme\TestBundle\Doctrine\DBAL\FooConnection;
use Doctrine\DBAL\Connection;

class FooConnection extends Connection
{
// custom query...
public function findBarByDate(\DateTime $date)
{
$stmt = $this->prepare('SELECT * FROM bar WHERE date = :date');
$stmt->bindValue('date', $date, 'datetime');
$stmt->execute();

return $stmt->fetch();
}
}

请注意,包装类必须扩展\Doctrine\DBAL\Connection

  1. 在任何需要的地方使用您的查询:
$date   = new \DateTime();
$conn = $this->getDoctrine()->getConnection('foo');
$result = $conn->findBarByDate($date);

希望这对您有所帮助!

关于php - 在 Symfony2 中组织可重用 DBAL 查询的最佳实践?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8241084/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com