В настоящий момент я работаю над проектом Symfony2. По большей части это стандартно; Я использую слой ORM для взаимодействия с базой данных через мои сущности. Проблем нет.
Тем не менее, мне нужно сделать нечетные запросы к небольшой части таблиц в существующей схеме в другом месте в системе, которая содержит то, что я бы назвал «ссылкой»: такие вещи, как коэффициенты конверсии валют и т. Д. У меня есть только SELECT
доступ к этой схеме.
Я установил другое соединение, и я перешел на уровень DBAL, чтобы сделать запросы на эту схему, которая до сих пор работает очень хорошо.
Моя проблема заключается в том, что, хотя это редкость, я думаю, что мне нужно будет повторить некоторые из моих запросов DBAL в более чем одном месте в моем приложении; Я хотел бы реорганизовать эти запросы в какой-то репозиторий, где их легче использовать / проверять / и т. Д. Я думал о создании сущностей для таблиц, но я чувствую, что в этом случае это слишком много. Правильно ли я полагаю, что вам нужны сущности для создания репозитория?
Вместо этого мне интересно, есть ли способ «Symfony» для этого? Что-то приятное и элегантное 🙂
Благодаря! Дарраг
2013-10-03
Простите меня за редактирование двухлетнего ответа … Однако несколько человек поставили под сомнение существующий подход, и хотя он работает (и хорошо работал для моего конкретного случая использования), определение сервисов – это, конечно, способ Symfony .
Никто не привел пример, поэтому для справки / полноты я обновлю свой ответ. Я должен признать, что я не был действительно уверен в определении пользовательских сервисов, когда я изначально опубликовал этот ответ, но мы живем и учимся.
Исходный ответ сохраняется ниже.
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%
src/Acme/TestBundle/Resources/config/services.yml
. foo_connection
указанное выше DBAL foo_connection
в службу. services: foo_query_service: class: Acme\TestBundle\Services\FooQueryService arguments: - @doctrine.dbal.foo_connection
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(); } }
Например, в контроллере …
/** * @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
: 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);
Надеюсь это поможет!
Вау, ваш ответ подразумевает, что у вас есть все ваши запросы в тех же местах для каждой таблицы.
Мне не нравится эта оболочка, я предпочитаю иметь услуги. Одна услуга за стол или пакет, это зависит от того, сколько у вас большого количества таблиц и как вы хотите, чтобы ваши запросы были организованы.
Затем я передаю требуемое соединение как аргументы службы, и все.