春天 + Hibernate - 多个数据库
我正在创建一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在“MySuperService”中,您使用两个bean(MyMainDao 和MyCustomerDao)。 这是可行的,因为它们有不同的类型(Java 类)。
如果您想要一个可以返回其中一个的工厂,请使用与“MySuperService”中相同的方法,但不要依赖于类型,而是为两个 bean 指定不同的名称。 这样,您的工厂就可以按名称查找它们,您可以说:
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: