Spring + Hibernate - несколько баз данных

125
13

Я создаю веб-сайт asp.net mvc, и мне нужен совет. У меня есть следующие слои:


    базы данных
    уровень доступа к данным (объекты домена, DAO-интерфейсы + реализации DAO на основе NHibernate)
    уровень обслуживания (служебные интерфейсы + реализация служб)
    уровень представления (ASP.NET MVC)

На самом деле существует несколько баз данных:


    одна база данных с общими данными и списком клиентов
    множество баз данных - каждая база данных для одного клиента (с той же структурой, но не на том же сервере)

DAO и сервисы "связаны" следующим образом:


MyMainService (contains business logic)
MyMainDao (contains data access functions)
MyMainSessionFactory (session factory for the main database)
MyMainDbProvider (db provider with a connection to the main database)

или


MyCustomerService (contains business logic)
MyCustomerDao (contains data access functions)
MyCustomerSessionFactory (session factory for the customer database)
MyCustomerDbProvider (db provider with a connection to the main database)

или смешанный (одновременно используя обе базы данных):


MySuperService (contains business logic)
MyMainDao (contains data access functions)
MyMainSessionFactory (session factory for the main database)
MyMainDbProvider (db provider with a connection to the main database)
MyCustomerDao (contains data access functions)
MyCustomerSessionFactory (session factory for the customer database)
MyCustomerDbProvider (db provider with a connection to the main database)

Я использую заполнители свойств (и PropertyPlaceholderConfigurer) в обоих провайдерах.


И здесь мы подошли к точке, где я хочу использовать эти службы (в ASP.NET MVC-контроллере):


Нет проблем, если я хочу использовать MyMainService - я использую DI, и все работает нормально.


Но если я хочу использовать MyCustomerService или MySuperService, я не думаю, что могу использовать DI, но более "зависимость".
Я думаю, что я должен создать какой-то "сервис factory", на который я передам идентификатор клиента и службу factory
вернет мне сервис с подключением к соответствующей базе данных. Что-то вроде:


TService GetService<TService>(int customerId)
{
CustomerInfo info = GetCustomerInfo(customerId);
IConfigurableApplicationContext context = (IConfigurableApplicationContext)WebApplicationContext.GetRootContext();
PropertyPlaceholderConfigurer conf = (PropertyPlaceholderConfigurer)context.GetObject("PropertyPlaceholderConfigurer");
conf.Properties["db.datasource"] = info.DataSource;
conf.Properties["db.user"] = info.UserName;
conf.Properties["db.password"] = info.Password;
conf.Properties["db.database"] = info.DatabaseName;
context.AddObjectFactoryPostProcessor(conf);
context.Refresh();
IEnumerator it = context.GetObjectsOfType(typeof(TService)).Values.GetEnumerator();
if (it.MoveNext())
{
return (TService)it.Current;
}
}

Правильно ли это, или я совершенно не прав, и я должен сделать это по-другому?


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


  IMyService s1 = GetService<IMyService>(1);
IMyService s2 = GetService<IMyService>(2);
s1.importData(s2.exportData());

Любые советы будут оценены.


Большое спасибо!

спросил(а) 2021-01-25T21:38:52+03:00 4 месяца, 4 недели назад
1
Решение
100

В "MySuperService" вы используете как beans (MyMainDao, так и MyCustomerDao). Это работает, поскольку они имеют разные типы (классы Java).


Если вы хотите вернуть factory, используйте тот же подход, что и в "MySuperService", но вместо того, чтобы полагаться на тип, укажите два beans разных имен. Таким образом, ваш factory может найти их по имени, и вы можете сказать:

connector = factory.lookup("name");

ответил(а) 2021-01-25T21:38:52+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема