目前,我正在从事Symfony2项目。在大多数情况下,这是完全标准的;我正在使用ORM层通过我的实体与数据库进行交互。那里没有问题。
但是,我确实需要很少查询系统中其他地方现有模式中的少数几张表,其中包含我称为“引用”信息的信息:诸如货币换算比率之类的信息。我只有SELECT
可以访问此架构。
我建立了另一个连接,并已进入DBAL层以对该模式进行查询,到目前为止,该模式一直运行良好。
我的问题是,尽管不常见,但我认为我需要在应用程序的多个位置重复一些DBAL查询。我想将这些查询重构到某种存储库中,在这些存储库中更容易使用/测试/等。我曾考虑过为表创建实体,但是在这种情况下,我觉得这太过分了。我是否正确,认为您需要实体来创建存储库?
相反,我想知道是否有一种“Symfony方式”来做到这一点?优雅的东西:)
谢谢!
达拉格
最佳答案
更新
2013-10-03
原谅我编辑了两年的答案...但是,有些人对现有方法提出了质疑,尽管它可行(并且对于我的特定用例而言效果很好),但是定义服务当然是 Symfony方式。
没有人提供示例,因此,为了引用/完整性,我将更新我的答案。我不得不承认,当我最初发布此答案时,我对定义自定义服务并不是很满意,但是我们生活并学习。
原始答案保留在下面。
1.创建一个附加的DBAL连接
foo
中创建连接app/config/config.yml
。 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.配置服务
src/Acme/TestBundle/Resources/config/services.yml
。 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();
}
完成:)感谢
Acayra
和koskoz
的反馈。好的,我想我找到了在这种情况下适用于我的解决方案。
实际上,我还对创建实体/管理器有了另一种看法-实际上似乎缺少有关将特定实体映射到多个管理器的Symfony2文档。在这种情况下,它似乎仍然是一种过大的方法(并且“引用”模式非常困惑)。
幸运的是,可以为DBAL连接指定一个包装器类,然后将查询抽象到特定的方法中。
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%
<?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
。$date = new \DateTime();
$conn = $this->getDoctrine()->getConnection('foo');
$result = $conn->findBarByDate($date);
希望这可以帮助!
关于php - 在Symfony2中组织可重用DBAL查询的最佳实践?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8241084/