春天 + Hibernate - 多个数据库

发布于 2024-07-25 15:19:37 字数 2709 浏览 8 评论 0原文

我正在创建一个 ASP.NET MVC 网站,我需要建议。 我有以下几层:

  • 数据库
  • 数据访问层(域对象、DAO 接口 + 基于 NHibernate 的 DAO 实现)
  • 服务层(服务接口 + 服务实现)
  • 表示层 (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,而是更多的“依赖拉动”。 我认为我应该创建某种“服务工厂”,我将向其中传递客户 ID 和服务工厂 将返回带有到相应数据库的连接的服务。 例如:

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

任何建议将不胜感激。

非常感谢!

I am creating an asp.net mvc web site and I need an advice. I have following layers:

  • database
  • data access layer (domain objects, DAO interfaces + DAO implementations based on a NHibernate)
  • service layer (service interfaces + service implementations)
  • presentation layer (ASP.NET MVC)

There are actually several databases:

  • one database with a common data and customers list
  • many databases - each database for one customer (with the same structure, but not necessery on the same server)

DAO's and services are "linked" in this way:

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)

or:

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)

or mixed (using both databases at the same time):

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)

I am using property placeholders (and the PropertyPlaceholderConfigurer) in both providers.

And here we came to the point where I want to use this services (in a ASP.NET MVC controller):

There is no problem if I want to use MyMainService - I use DI and everything works fine.

But if I want to use MyCustomerService or MySuperService I don't think that I can use DI, but more "dependency pull".
I think that I should create some kind of a "service factory" to which I will pass a customer ID and the service factory
will return me the service with the connection to the appropriate database. Something like:

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;
  }
}

Is this the right way or am I completely wrong and I should do this some other way?

Note: There will be a case when I will want to use the same service for different customers at the same time, for example:

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

Any advice would be appreciated.

Many thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一片旧的回忆 2024-08-01 15:19:37

在“MySuperService”中,您使用两个bean(MyMainDao 和MyCustomerDao)。 这是可行的,因为它们有不同的类型(Java 类)。

如果您想要一个可以返回其中一个的工厂,请使用与“MySuperService”中相同的方法,但不要依赖于类型,而是为两个 bean 指定不同的名称。 这样,您的工厂就可以按名称查找它们,您可以说:

connector = factory.lookup("name");

In the "MySuperService", you use both beans (MyMainDao and MyCustomerDao). This works since they have different types (Java classes).

If you want a factory which can return either, use the same approach as in "MySuperService" but instead of relying on the type, give the two beans different names. That way, your factory can look them up by name and you can say:

connector = factory.lookup("name");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文