在我的一个项目中,我有一个管理多个客户端(如果您愿意,也可以是客户)的应用程序。对于它们中的每一个,我在数据库上都有一个专用的模式。 但是,该应用程序一次只处理一个客户端,即用户必须在应用程序中从一个客户端切换到另一个客户端(在运行时,无需重新启动应用程序)才能从这个新客户端访问数据。
对于此类项目,您将如何管理连接以及持久层?
我想为此使用 Hibernate。在处理多个数据库/模式时,我必须非常小心的几点是什么?
在这种情况下,Spring 能帮上忙吗?
如果我不够清楚,让我举例说明情况。
假设我的应用程序可以处理两个客户端:clientONE
和 clientTWO
.
我已经实现了一个类,它可以为我提供给定客户端的数据库架构、用户、密码和连接字符串。
每个客户端都有一个债务人列表,但不幸的是,clientONE
的 DEBTOR 表结构不一样。和 clientTWO
.
连表名/列名都不一样...
所以我可以为每个客户创建一个债务人类(我使用 Hibernate 注释):
@Entity
@Table(name = "T_DEBTOR_ONE")
...
public class ClientOneDebtor {
@Id
@Column(name = "ID_DEBTOR")
private String idDebtor;
...
}
和:
@Entity
@Table(name = "T_DEBTOR_TWO") // Table names are not the same among the different schemas...
...
public class ClientTwoDebtor {
@Id
@Column(name = "DEBTOR_ID") // It's just to show that the same information is stored in a column that has not the same name.
private String idDebtor;
...
}
理想情况下,我会尝试拥有一个共同的 Debtor
类(这里是一个抽象类,但我可能会使用一个接口(interface)):
public abstract class AbstractDebtor {
public abstract String getIdDebtor();
...
}
@Entity
@Table(name = "T_DEBTOR_ONE")
...
public class ClientOneDebtor extends AbstractDebtor {
@Id
@Column(name = "ID_DEBTOR")
private String idDebtor;
...
}
@Entity
@Table(name = "T_DEBTOR_TWO")
...
public class ClientTwoDebtor extends AbstractDebtor {
@Id
@Column(name = "DEBTOR_ID") // It's just to show that the same information is stored in a column that has not the same name.
private String idDebtor;
...
}
这样,我将更容易在我的 DAO/服务层中操作 Debtor 对象,因为我不需要为每个客户端复制我的 DAO 和服务。
例如,从 DAO 获取所有债务人列表的方法将是 public List<AbstractDebtor> getAllDebtors() { ... }
.
那么,当我更改由我的应用程序管理的客户端时,我将如何更改上下文?
换句话说,我如何向 Hibernate(或 Spring?)表明我想对当前由我的应用程序管理的客户端使用正确的持久性对象(ClientOneDebtor
或 ClientTwoDebtor
)?
如果您认为我走错了方向,请不要犹豫,分享您对如何解决此类问题的想法...
编辑第一个答案:
我需要处理的不同模式的数量大约为 15 - 20。除此之外,我只需要映射他们表的一小部分。
我也知道,为每个客户/客户提供一个模式并不是存储数据的最佳解决方案。然而,这种架构已经存在 5 年了,我们可能会在明年(在最好的情况下 ;) )只迁移到一个架构。
最佳答案
如果一次只需要一个,那么事情就简单多了。只需为每个数据库创建一个 SessionFactory
。避免使用 HibernateUtils
static SessionFactory
实例方法,您不会有任何问题。
如果您没有太多数据库(数百个),使用 Spring 执行此操作的一种巧妙方法是为每个包含 SessionFactoryBean
的数据库实例化一个单独的 Spring ApplicationContext
> 和 DataSource
专用于该数据库的配置。
您可以使用 PropertyOverrideConfigurer
和公共(public)父 ApplicationContext
之类的 Spring 机制来提取所有公共(public)内容,以便您的许多子 ApplicationContext
体积小且易于维护。
然后,当请求到来时,只需选择您要使用的 ApplicationContext
并开始从中提取 bean。
如果你想在没有 Spring 的情况下这样做,你也可以创建多个 SessionFactory
实例并将“当前”实例存储在静态 ThreadLocal
中。
关于java - 如何使用 Hibernate 处理多个数据库模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1662427/