一尘不染

如何使用Hibernate处理几个数据库模式?

hibernate

在我的一个项目中,我有一个管理多个客户(或客户,如果您愿意的话)的应用程序。对于他们每个人,我在数据库上都有一个专用的架构。但是,应用程序一次只处理一个客户端,即,用户必须从应用程序中的一个客户端切换到另一个客户端(在运行时,不重新启动应用程序),以便从该新客户端访问数据。

您将如何管理此类项目的连接以及持久层?

我想为此使用hibernate。在处理几个数据库/模式时,我必须特别注意哪些方面?

在这种情况下,Spring可以提供任何帮助吗?


如果我不够清楚,请举一个例子来说明情况。想象一下,我的应用程序可以处理两个客户端:clientONEclientTWO。我已经实现了一个类,该类可以为我提供给定客户端的数据库架构,用户,密码和连接字符串。

每个客户端有债务人的名单,但遗憾的是,债务人表结构是不一样的clientONEclientTWO。甚至表/列的名称也不一样…

因此,我可以为每个客户端创建一个债务人类(我使用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类(这是一个Abstract类,但是我可以使用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?)指示要使用与当前由我的应用程序管理的客户端有关的正确的持久性对象(ClientOneDebtorClientTwoDebtor)?

如果您认为我走错了方向,请不要犹豫,就如何解决此类问题分享您的想法…


编辑有关第一个答案的信息:

我将需要处理的不同模式的数量大约为15-20。除此之外,我只需要映射它们表的一小部分。

我也知道,每个客户/客户只有一个架构并不是存储数据的最佳解决方案。但是,这种体系结构已有5年的历史了,我们可能会在下一年(仅在最佳情况下;))使用一种模式。


阅读 222

收藏
2020-06-20

共1个答案

一尘不染

如果一次只需要一个,那么它将变得更加简单。只需创建一个SessionFactory每个数据库。避免使用HibernateUtils静态SessionFactory实例方法,这样就不会有任何问题。

如果您没有太多的数据库(数百个),使用Spring的一种巧妙方法是ApplicationContext为每个数据库实例化一个单独的Spring
,其中包含专门用于该数据库的SessionFactoryBeanDataSource配置。

您可以使用Spring机制(例如PropertyOverrideConfigurer和共同的父母)ApplicationContext来排除所有共同的东西,以使您的许多孩子ApplicationContext小而可维护。

然后,当有请求进入时,只需选择ApplicationContext您要使用的对象,然后开始将其拉出即可。

如果要在没有Spring的情况下执行此操作,则还可以创建多个SessionFactory实例并将“当前”实例存储在static中ThreadLocal

2020-06-20