Java 如何使用Hibernate处理多个DB模式?
在我的一个项目中,我有一个管理多个客户机(或者客户机,如果您愿意的话)。对于它们中的每一个,我在数据库上都有一个专用的模式。 但是,应用程序一次只处理一个客户机,即用户必须在应用程序中从一个客户机切换到另一个客户机(在运行时,不重新启动应用程序),以便从新客户机访问数据 对于此类项目,您将如何管理连接以及持久性层 我想用Hibernate来做这个。在处理多个数据库/模式时,我必须非常小心的几点是什么 Spring在这种情况下有什么帮助吗Java 如何使用Hibernate处理多个DB模式?,java,hibernate,persistence,database-connection,Java,Hibernate,Persistence,Database Connection,在我的一个项目中,我有一个管理多个客户机(或者客户机,如果您愿意的话)。对于它们中的每一个,我在数据库上都有一个专用的模式。 但是,应用程序一次只处理一个客户机,即用户必须在应用程序中从一个客户机切换到另一个客户机(在运行时,不重新启动应用程序),以便从新客户机访问数据 对于此类项目,您将如何管理连接以及持久性层 我想用Hibernate来做这个。在处理多个数据库/模式时,我必须非常小心的几点是什么 Spring在这种情况下有什么帮助吗 如果我不够清楚,让我用一个例子来解释情况。 假设我的应用
如果我不够清楚,让我用一个例子来解释情况。 假设我的应用程序可以处理两个客户端:
clientONE
和clientTWO
。
我已经实现了一个类,它可以为给定客户机提供数据库模式、用户、密码和连接字符串
每个客户机都有一个债务人列表,但不幸的是,clientONE
和clientTWO
的债务人表结构不同。
甚至表/列的名称也不相同
因此,我可以为每个客户机创建一个债务人类(我使用Hibernate注释):
以及:
理想情况下,我将尝试使用一个公共的类(这里是一个抽象类,但我可以使用一个接口):
这样,我就更容易在我的DAO/服务层中操作债务人对象,因为我不需要为每个客户机复制我的DAO和服务。
例如,从DAO获取所有债务人列表的方法将是public list getalldeborts(){…}
那么,当我更改应用程序管理的客户机时,如何更改上下文?
换句话说,我将如何向Hibernate(或Spring?)表明我希望使用与当前由我的应用程序管理的客户端相关的正确持久性对象(ClientOneDebtor
或ClientTwoDebter
)
如果你认为我走错了方向,请毫不犹豫地分享你对如何解决这类问题的想法
编辑第一个答案:
我需要处理的不同模式的数量大约是15-20个。除此之外,我只需要映射它们表的一小部分
我还知道,每个客户机/客户有一个模式并不是存储数据的最佳解决方案。然而,这种架构已经存在了5年,我们可能在下一年只使用一种架构(在最好的情况下),如果每次只需要一种架构,那么它会变得更简单。只需为每个数据库创建一个SessionFactory
。避免使用HibernateUtils
staticSessionFactory
实例方法,您将不会遇到任何问题
如果没有太多的数据库(数百个),使用Spring实现这一点的一个好方法是为每个数据库实例化一个单独的SpringApplicationContext
,其中包含专门针对该数据库的SessionFactoryBean
和DataSource
配置
您可以使用Spring机制,如PropertyOverrideConfiguler
和一个公共父级ApplicationContext
来分解所有公共内容,以便您的许多子级ApplicationContext
都很小且可维护
然后,当请求传入时,只需选择要使用的ApplicationContext
,并开始从中提取bean
如果不想使用Spring,还可以创建多个SessionFactory
实例,并将“当前”实例存储在静态ThreadLocal
中不幸的是,现实世界通常需要多个数据库/模式,尤其是当您的供应商产品的数据库必须与您的公司数据库不同时
<> P>制作任意数量的数据库将是一团糟,为此,你真的应该考虑更好的数据组织形式。但是对于一组固定的(希望很小的)数据库,只需在持久性配置中为它们定义一个单独的PersistenceUnit(这意味着一个单独的EntityManager)
使用图示的继承方案,假设框架允许,您可以为每个派生类分配适当的EntityManager
@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;
...
}
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;
...
}