Как проектировать DAO при динамическом изменении источника данных - PullRequest
4 голосов
/ 05 февраля 2009

Обычно при определении DAO у вас будет установщик для источника данных в объекте DAO. Моя проблема в том, что наш источник данных динамически меняется в зависимости от запроса к серверу. каждый запрос может иметь доступ к другому экземпляру базы данных.

Запрос содержит логические свойства, которые впоследствии можно использовать для получения соединения с БД запроса.

Так что, когда зависимость вводит DAO в объект бизнес-логики, мне нужен способ установить свойства DAO во время выполнения (не во время настройки).

Одним из решений является сохранение источника данных в локальном потоке, но мне не очень нравится возиться с локальными переменными потока.

Другим вариантом является использование метода initialize для объекта бизнес-логики, который вызывает инициализацию в DAO со свойствами запроса.

Я полагаю, это общая проблема, можете ли вы предложить общее решение?

Ответы [ 5 ]

8 голосов
/ 05 февраля 2009

Ваша проблема немного сбивает с толку. Казалось бы, один доступ к DAO к нескольким различным источникам данных - это кошмар обслуживания. В результате вы должны определить один интерфейс DAO, содержащий все методы, которые вы хотите вызвать. Для каждой базы данных, к которой вы подключаетесь, я бы создал новый класс, который реализует ваш интерфейс DAO. Это позволяет вам иметь несколько реализаций. Затем я бы сохранил эти реализации (каждая из которых имеет собственный источник данных) на карте (java.util.Map), используя ваши «логические свойства» в качестве ключа к карте. Поскольку все ваши реализации DAO реализуют ваш интерфейс, вы сможете привести их к интерфейсу и использовать их взаимозаменяемо. На вашем бизнес-объекте вы внедрите карту реализаций DAO. Надеюсь, это поможет вашему дизайну.

6 голосов
/ 08 февраля 2009

Вы можете посмотреть на этот класс:

http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.html

Это позволит вашим сервисным объектам и объектам доступа к данным не знать, что существует какое-либо представление о динамических источниках данных.

Как правило, вам нужно реализовать фильтр сервлетов и использовать ThreadLocal, чтобы реализация DataSourceLookup, используемая AbstractRoutingDataSource, могла легко получить доступ к параметрам запроса, которые определяют, какой DataSource возвращается. Если вы действительно хотите этого избежать, вы можете реализовать фильтр сервлетов, который устанавливает свойства для bean-объекта в области запросов и внедрить этот bean-компонент в написанную вами реализацию DataSourceLookup. Bean-объекты в области запросов по-прежнему используют ThreadLocal в своей реализации, но, по крайней мере, таким образом, это значение Spring, а не ваше, и вам не нужно об этом беспокоиться. :)

Подобный подход подробно описан в этой записи блога от команды Spring:

http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/

5 голосов
/ 05 февраля 2009

У меня была такая проблема в проекте клиент / сервер. Клиентский и серверный проекты совместно используют интерфейсы Dao. И когда я использовал для работы с базой данных, мне нужно было выбрать подходящую реализацию Дао. Мое решение было так:

IVehicleDao vehicleDao =daoFactory.Get<IVehicleDao>(parameters);
vehicleDao.doSomething();

Получите dao из Factory, передав параметры. Внутри фабрики Dao решите, какую реализацию Dao вернуть.

5 голосов
/ 05 февраля 2009

Похоже, ваша проблема в том, что вы создаете один экземпляр DAO для своего приложения. Вам нужно либо создать отдельный экземпляр для каждого источника данных (возможно, создавая какой-то контроллер dao, чтобы управлять всем этим для вас), либо позволить вашим методам в dao быть статичными и передавать всю информацию о том, как подключиться к источнику данных вместе с данные, которые вы сохраняете в каждом методе.

2 голосов
/ 21 августа 2010

Я уже сделал это. Вам нужно создать по одному DAO для каждого класса, и в области действия вашего DAO вам нужно передать DATASOURCE и, наконец, один класс CONTROLLER, где вы делаете динамический вызов DAO.

...