Java 如何配置hibernate以使用特定于上下文的连接信息?

Java 如何配置hibernate以使用特定于上下文的连接信息?,java,hibernate,connection-pooling,c3p0,Java,Hibernate,Connection Pooling,C3p0,我正在使用Hibernate编写一个JavaSE(注意,不是JavaEE)应用程序,我需要为每个执行线程提供到Hibernate的不同连接。这些连接必须是池连接,并且每个连接至少具有不同的身份验证,可能还有不同的JDBCURL。这些连接将被重新使用(从池化要求可以推断) 我必须覆盖Hibernate/C3P0/等的哪些部分?这可以通过这些工具实现吗,或者我需要编写自己的池数据源吗?这里有两个问题: 连接不是线程安全的,因此每个线程都必须有自己的连接。因为您使用的是Hibernate,所以应用程序

我正在使用Hibernate编写一个JavaSE(注意,不是JavaEE)应用程序,我需要为每个执行线程提供到Hibernate的不同连接。这些连接必须是池连接,并且每个连接至少具有不同的身份验证,可能还有不同的JDBCURL。这些连接将被重新使用(从池化要求可以推断)


我必须覆盖Hibernate/C3P0/等的哪些部分?这可以通过这些工具实现吗,或者我需要编写自己的池数据源吗?

这里有两个问题:

  • 连接不是线程安全的,因此每个线程都必须有自己的连接。因为您使用的是Hibernate,所以应用程序看到的实际上是从SessionFactory获得的会话。要利用此功能,请调用SessionFactory#getCurrentSession()方法,并在hibernate.cfg.xml中配置当前会话上下文: <property name="current\_session\_context\_class">thread</property> 线 如果您在hibernate.cfg.xml中正确配置了线程池(使用c3po或任何您喜欢的池机制),那么每个线程都将从该池获得一个连接
  • 要维护应用程序可能需要使用的多个数据源,则需要为要访问的每个JDBC url配置单独的SessionFactory。在您的应用程序中,您需要使用SessionFactory进行一些选择(例如“客户端ID”),使用它您可以管理映射或类似数据结构中的每个SessionFactory实例(在Java EE应用程序中,您可以从JNDI获得引用)
  • 概括地说,SessionFactory基本上是围绕数据源(和助理连接池)的巨大包装器。它是只读的(因此是线程安全的)、重量级的、静态的、只构造一次的,并且知道关于给定数据源所需的一切

    另一方面,会话本质上是连接的轻量级包装器。它不是线程安全的,通常寿命很短,打算使用后扔掉


    希望这有帮助

    我认为最好的做法是为每个数据源创建一个
    SessionFactory
    ,其中可能包含池连接——这是eqbridges在回答中建议的

    现在,Hibernate确实有一个
    ConnectionProvider
    hook,因此我想您可以编写一个实现,根据当前执行线程和一些附加参数,将
    Connection
    s返回到不同的数据源。从理论上讲,您可以有一个
    SessionFactory
    实例,它将使用自定义
    ConnectionProvider
    实现提供的到不同数据库的不同连接。但是,一个
    SessionFactory
    保存了相当多的数据,当为一个工作单元打开
    会话时,Hibernate会在内部使用这些数据。另外,还有一个与之相关的二级缓存

    不幸的是,工厂和您从中打开的
    会话在这样一个提供者面前将如何表现,这是任何人的猜测。对我来说,这就像是一个黑客,我怀疑它是否被认为是
    会话工厂
    的可行用例。它可能会导致各种各样的、可能非常微妙的bug或数据损坏


    另一方面,请确保准确衡量创建多个
    会话工厂的成本-它可能没有您想象的那么高。请务必将其与简单打开所需JDBC连接的成本进行比较。我不知道您可能会得到什么样的结果,但我认为您应该先确定性能,然后再求助于更粗糙的解决方案。

    这对某些人有帮助。。。但是,如果我需要会话工厂(因为没有更好的词)选择从数据源获取哪个连接,该怎么办?也许我需要一个元池?假设您有3个数据源(a、B和C)。为每个会话工厂配置一个会话工厂,将每个会话工厂的连接池设置为至少有0个连接(使其延迟初始化)。然后,让您的应用程序根据是否需要a、B或C从该集中选择会话工厂。使用会话工厂获取会话,其中包含从连接池获得的连接。如果这不是你想要表达的意思,你能更清楚地说明你所说的“选择”是什么意思吗?我试图避免多个会话工厂的成本;模式和映射对于所有连接都是相同的,并且启动会话工厂非常昂贵。如果我能安排它,使连接成为改变的轴心,而不是会话工厂,那么我就可以大大降低会话管理的成本。会话工厂的契约是,它一旦构建就不可变。如果您找到一种方法来交换连接信息以切换它所使用的数据源,则不会指定结果,因为您违反了这一约定。虽然会话工厂“繁重”,但它们并不笨重。做一些测试和测量。