如何使用Hibernate处理几个数据库模式? [英] How to handle several DB schemas with Hibernate?

查看:108
本文介绍了如何使用Hibernate处理几个数据库模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的一个项目中,我有一个管理多个客户端(或客户,如果你喜欢)的应用程序。对于它们中的每一个,我在数据库上有一个专用的模式。
然而,应用程序一次只能处理一个客户端,即用户必须在应用程序中从一个客户端切换到另一个客户端(在运行时,不重新启动应用程序),以便从该新客户端访问数据。



如何管理这种项目的连接以及持久层?



我想使用Hibernate的。



在这种情况下,Spring可以帮助什么吗?






如果我不够清楚,让我用一个例子解释一下情况。
想象一下,我的应用程序可以处理两个客户端: clientONE clientTWO
我已经实现了一个类,它可以为给定的客户端提供数据库模式,用户,密码和连接字符串。



每个客户都有一个债务人列表,但不幸的是,对于 clientONE clientTWO ,DEBTOR表结构不同。
即使表/列的名称不一样...



所以我可以为每个客户端创建一个债务类(我使用Hibernate注释):

  @Entity 
@Table(name =T_DEBTOR_ONE)
...
class ClientOneDebtor {

@Id
@Column(name =ID_DEBTOR)
private String idDebtor;

...

}

  @Entity 
@Table(name =T_DEBTOR_TWO)//表名称不同的模式...
...
public class ClientTwoDebtor {

@Id
@Column(name =DEBTOR_ID)//只是为了显示相同的信息存储在不具有相同名称的列中。
private String idDebtor;

...

}

,我将尝试有一个共同的 Debtor 类(这里是一个抽象类,但我可以使用一个接口):

  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)//只是为了显示相同的信息存储在一个具有不同名称的列。
private String idDebtor;

...

}

方式,它将更容易操作我的DAO /服务层中的Debtor对象,因为我不需要为每个客户端复制我的DAO和服务。
例如,从DAO获取所有Debtors的列表的方法将是 public List< AbstractDebtor>因此,当我更改由我的应用程序管理的客户端时,我如何更改上下文?
换句话说,我如何向Hibernate(或Spring?)表明我想使用正确的持久化对象( ClientOneDebtor 关于目前由我的应用程序管理的客户端的客户端(ClientTwoDebtor )?



如果你认为我的方向错误,分享您对如何解决这类问题的想法...






编辑第一个答案:



我需要处理的不同模式的数量约为15 - 20.除此之外,我只需要映射一个



我也知道每个客户端/客户有一个模式不是存储数据的最佳解决方案。但是,这种架构自5年就存在,我们可能在下一年仅迁移到一个模式(在最好的情况下)。

解决方案

如果每次只需要一个,这将使它更简单。只需为每个数据库创建一个 SessionFactory 。避免 HibernateUtils static SessionFactory 实例方法,你不会有任何问题。



如果你没有太多的数据库(数百),用Spring做一个简单的方法是为每个实例化一个单独的Spring ApplicationContext 其中包含专门为该数据库配置的 SessionFactoryBean DataSource 配置。



您可以使用 PropertyOverrideConfigurer 等常用父类 ApplicationContext

然后当请求进来时,只需选择



如果你想在没有Spring的情况下使用它,你需要使用它。也可以创建多个 SessionFactory 实例,并将当前实例存储在静态 ThreadLocal 中。


In one of my projects, I have an application that manages several clients (or customer if you prefer). For each of them, I have a dedicated schema on a database. However, the application handles only one client at a time, i.e. the user must switch from one client to another in the application (at runtime, no restart of the application) in order to access the data from this new client.

How would you manage the connections, as well as the persistence layer, for this kind of project?

I want to use Hibernate for that. What are the points on which I must be really carefull when dealing with several database / schemas ?

Can Spring be of any help in this case?


If I am not clear enough, let me explain the situation with an example. Imagine that my application can handle two clients: clientONE and clientTWO. I already implemented a class that can provide me the database schema, user, password and connection String for a given client.

Each client have a list of debtors, but unfortunately, the DEBTOR table structure is not the same for clientONE and clientTWO. Even the names of tables / columns are not the same...

So I can create one debtor class per client (I use Hibernate annotations):

@Entity
@Table(name = "T_DEBTOR_ONE")
...
public class ClientOneDebtor {

    @Id
    @Column(name = "ID_DEBTOR")
    private String idDebtor;

    ...

}

and:

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

    ...

}

Ideally, I will try to have a common Debtor class (here is an Abstract class, but I may use an 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;

    ...

}

This way, it will be easier for me to manipulate the Debtor objects in my DAO / Service layer, as I will not need to duplicate my DAO and Services for every client. For example, the method from DAO to get the list of all Debtors will be public List<AbstractDebtor> getAllDebtors() { ... }.

So, how would I change the context when I change the client managed by my application? In others words, how would I indicate to Hibernate (or Spring?) that I want to use the correct persistence objects (ClientOneDebtor or ClientTwoDebtor) regarding the client that is currently managed by my application?

If you think that I am going in the wrong direction, do not hesitate to share your ideas on how to solve this kind of problem...


Edit regarding the first answers:

The number of different schemas I will need to handle is around 15 - 20. In addition to that, I will only need to map only a little subset of their tables.

I also know that having one schema per client/customer is not the best solution for storing data. However, this architecture exist since 5 years, and we may move to only one schema during the next year (in the best case ;) ).

解决方案

If only one at a time will every be required, it makes it much simpler. Simply create a SessionFactory per database. Avoid the HibernateUtils static SessionFactory instance approach and you won't have any problems.

A neat way to do this with Spring if you don't have too many databases (hundreds) is to instantiate a separate Spring ApplicationContext for each one that contains the SessionFactoryBean and DataSource configurations specially for that database.

You can use Spring mechanisms like PropertyOverrideConfigurer and a common parent ApplicationContext to factor out all the common stuff so that your many child ApplicationContexts are small and maintainable.

Then when a request comes in, just select the ApplicationContext you want to work with and start pulling beans out of it.

If you want to do it without Spring, you could also create multiple SessionFactory instances and store the "current" one in a static ThreadLocal.

这篇关于如何使用Hibernate处理几个数据库模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆