eclipse Hibernate:在同一个应用程序中使用两个不同的数据库模式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13877734/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 19:36:44  来源:igfitidea点击:

Hibernate: Using two different DataBase schemas in the same application

javamysqleclipsehibernate

提问by Alex

Context

语境

I'm creating a database environment where I'd like to split data in several different schemas to be used for different groups of users. Although, one of these databases should be shared to everyone due to it contains common entities.

我正在创建一个数据库环境,我想在其中拆分多个不同模式中的数据以供不同的用户组使用。尽管如此,这些数据库之一应该共享给所有人,因为它包含公共实体。

Suppose databases:

假设数据库:

  • DB1 - Common entities;
    • Wheels entity
  • DB2 - Group "A";
    • Cars entity
  • DB3 - Group "B";
    • Motorcycles entity
  • DB1 - 公共实体;
    • 车轮实体
  • DB2 - 组“A”;
    • 汽车实体
  • DB3 - “B”组;
    • 摩托车实体

I have three different projects:

我有三个不同的项目:

  • Project 1:
    • Wheels bean
  • Project 2:
    • Cars constructor
  • Project 3:
    • Motorcycles constructor
  • 项目一:
    • 轮子豆
  • 项目2:
    • 汽车制造商
  • 项目3:
    • 摩托车制造商

Problem

问题

I'm trying to access wheels (Project 1) from projects/schemas (2,"A") and (3,"B")

我正在尝试从项目/模式(2,“A”)和(3,“B”)访问轮子(项目 1)

First question: Is it possible? Second: How can I do it?

第一个问题:可以吗?第二:我该怎么做?

hibernate.cfg.xmlin project 2 is configured to

hibernate.cfg.xml在项目 2 中配置为

<property name="hibernate.connection.url">jdbc:mysql://99.999.999.99:3306/DB2</property>

This necessarily must restrict all the connections to DB2, or there's another way to add a new connection or work with all databases in 3306 port, or at least DB1?

这必然必须限制与 DB2 的所有连接,或者还有另一种方法来添加新连接或使用 3306 端口中的所有数据库,或者至少是 DB1?

Mapping the entities from project1 in project 2seems not to be succeeded too, like:

项目 2 中的项目 1映射实体似乎也没有成功,例如:

<mapping class="com.company.project1.Wheels"
        package="com.company.project1.Wheels" resource="com/company/project1/Wheels.hbm.xml"/>

Configuration

配置

  • Eclipse Indigo
  • MySql 5.5
  • Hibernate 3.0 (mapping through xml instead annotations)
  • Win 7
  • 日蚀靛蓝
  • mysql 5.5
  • Hibernate 3.0(通过 xml 映射而不是注解)
  • 赢7

Thanks for helping!

感谢您的帮助!

回答by Jigar Parekh

You can use @Table(catalog="")to specify database to which they belong to and then also can make relation across database.

您可以使用@Table(catalog="")指定它们所属的数据库,然后也可以跨数据库建立关系。

in your case Wheelmaps to DB1, Carto DB2 and MotorCycleto DB3 using catalog attribute.

在您的情况下Wheel,使用目录属性映射到 DB1、CarDB2 和MotorCycleDB3。

i have used this solution with MySQL and MSSQL and works perfectly fine. only constraint this has all three DB has to be in same database server and user which is being used to access db should have appropriate permission to all DB.

我已将此解决方案与 MySQL 和 MSSQL 一起使用,并且运行良好。唯一的约束是所有三个数据库都必须在同一个数据库服务器中,并且用于访问数据库的用户应该对所有数据库具有适当的权限。

As this solution just adds schema name against table in all queries.

由于此解决方案仅在所有查询中针对表添加模式名称。

回答by Viral Patel

I would divide my project in multiple self sustained projects. The Wheel project will be self sufficient project which takes care of Wheel entity.

我会将我的项目分成多个自我维持的项目。Wheel 项目将是自给自足的项目,它负责处理 Wheel 实体。

Project 1: Wheel This project will define Hibernate entities and DAO to access / modify wheel definitions. Also I would configure a separate datasource in this project which points to DB1. Entity classes:

项目 1:Wheel 该项目将定义 Hibernate 实体和 DAO 以访问/修改轮定义。此外,我将在该项目中配置一个指向 DB1 的单独数据源。实体类:

@Entity
public class Wheel {
}

DAO classes:

DAO 类:

@Repository
public class WheelDAO {
    @Persistence
    private EntityManager em;
}

Basically the idea is to separate application at DAO level. And manage transactions at Service level. Imaging WheelDAO (wired to DB1 datasource) and CarDAO (wired to DB2 datasource) and inject these in CarService.

基本上这个想法是在 DAO 级别分离应用程序。并在服务级别管理事务。成像 WheelDAO(连接到 DB1 数据源)和 CarDAO(连接到 DB2 数据源)并将它们注入 CarService。

DB1             DB2          DB2
 |               |            |
WheelDAO       CarDAO       MotorcycleDAO
  \_____________/                   |
   \_____|__________________________/     
         |                        |
         |                        | 
       CarService          MotorCycleService

I suggest to use Spring as IOC container to manage these dependency. Although you can achieve this without using Spring too.

我建议使用 Spring 作为 IOC 容器来管理这些依赖项。尽管您也可以在不使用 Spring 的情况下实现这一点。

回答by Festus Tamakloe

What you need is just a db connection factory which allows you to use db that you want when you need it.

您需要的只是一个 db 连接工厂,它允许您在需要时使用您想要的 db。

Take a look at the class below which you can adapte to resolve your issue

看看下面的课程,您可以调整以解决您的问题

import java.net.URL;
import java.util.HashMap;

import javax.security.auth.login.Configuration;

public class HibernateUtil {

    private static Log log = LogFactory.getLog(HibernateUtil.class);

    private static HashMap<String, SessionFactory> sessionFactoryMap = new HashMap<String, SessionFactory>();

    public static final ThreadLocal sessionMapsThreadLocal = new ThreadLocal();

    public static Session currentSession(String key) throws HibernateException {

        HashMap<String, Session> sessionMaps = (HashMap<String, Session>) sessionMapsThreadLocal.get();

        if(sessionMaps == null) {
            sessionMaps = new HashMap();
            sessionMapsThreadLocal.set(sessionMaps);
        }

        // Open a new Session, if this Thread has none yet
        Session s = (Session) sessionMaps.get(key);
        if(s == null) {
            s = ((SessionFactory) sessionFactoryMap.get(key)).openSession();
            sessionMaps.put(key, s);
        }

        return s;
    }

    public static Session currentSession() throws HibernateException {
        return currentSession("");
    }

    public static void closeSessions() throws HibernateException {
        HashMap<String, Session> sessionMaps = (HashMap<String, Session>) sessionMapsThreadLocal.get();
        sessionMapsThreadLocal.set(null);
        if(sessionMaps != null) {
            for(Session session : sessionMaps.values()) {
                if(session.isOpen())
                    session.close();
            }
            ;
        }
    }

    public static void closeSession() {
        HashMap<String, Session> sessionMaps = (HashMap<String, Session>) sessionMapsThreadLocal.get();
        sessionMapsThreadLocal.set(null);
        if(sessionMaps != null) {
            Session session = sessionMaps.get("");
            if(session != null && session.isOpen())
                session.close();
        }
    }

    public static void buildSessionFactories(HashMap<String, String> configs) {
        try {
            // Create the SessionFactory
            for(String key : configs.keySet()) {
                URL url = HibernateUtil.class.getResource(configs.get(key));
                SessionFactory sessionFactory = new Configuration().configure(url).buildSessionFactory();
                sessionFactoryMap.put(key, sessionFactory);
            }

        } catch(Exception ex) {
            ex.printStackTrace(System.out);
            log.error("Initial SessionFactory creation failed.", ex);
            throw new ExceptionInInitializerError(ex);

        } // end of the try - catch block
    }

    public static void buildSessionFactory(String key, String path) {
        try {
            // Create the SessionFactory
            URL url = HibernateUtil.class.getResource(path);
            SessionFactory sessionFactory = new Configuration().configure(url).buildSessionFactory();
            sessionFactoryMap.put(key, sessionFactory);

        } catch(Throwable ex) {

            log.error("Initial SessionFactory creation failed.", ex);
            throw new ExceptionInInitializerError(ex);

        } // end of the try - catch block
    }

    public static void closeSession(String key) {
        HashMap<String, Session> sessionMaps = (HashMap<String, Session>) sessionMapsThreadLocal.get();
        if(sessionMaps != null) {
            Session session = sessionMaps.get(key);
            if(session != null && session.isOpen())
                session.close();
        }
    }

} // end of the class

http://www.java-forums.org/

http://www.java-forums.org/