Spring + Hibernate - несколько баз данных - PullRequest
0 голосов
/ 30 июня 2009

Я создаю веб-сайт 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, но больше "вытягивание зависимости". Я думаю, что я должен создать некую «фабрику обслуживания», которой я передам идентификатор клиента и фабрику обслуживания. вернет мне сервис с подключением к соответствующей базе данных. Что-то вроде:

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());

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

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

1 Ответ

0 голосов
/ 30 июня 2009

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

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

connector = factory.lookup("name");
...