Hibernate JTA:读取每个环境的数据库连接参数

Hibernate JTA : Read DB connection parameters per environment

我正在编写一个 javaEE 应用程序,使用休眠。该应用程序将 运行 在多个环境(dev、qa、prod 等)上运行,并且每个环境都有单独的数据库。我想为每个环境分别设置 jdbc-url、用户名、密码等休眠属性。

我目前的 persistence.xml 看起来像:

    <persistence-unit name="PU" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <validation-mode>CALLBACK</validation-mode>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect" />
            <property name="hibernate.hbm2ddl.auto" value="validate" />

            <property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
            <property name="hibernate.event.merge.entity_copy_observer" value="allow"/>

            <property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver"/>
            <property name="hibernate.connection.url" value="jdbc:oracle:thin:@host/schema"/>

            <property name="hibernate.connection.username" value="abc"/>
            <property name="hibernate.connection.password" value="***"/>    

        </properties>
    </persistence-unit>

我在 java 代码中使用如下持久性单元:

@PersistenceContext(unitName = "PU")
private EntityManager em; 

有没有一种方法可以将存储在单独属性文件中的休眠属性注入到不同环境的 EntityManager 中?

请注意,我使用的是 JTA,因此无法使用 EntityManagerFactory。另外我不是也不想使用 spring.

既然您不想使用 Spring 等外部库来 bootstrap 您的持久性单元,为什么不使用您的构建系统来执行此操作。如果您使用的是 maven,则可以混合使用 maven filtering and profiles 来根据属性文件进行过滤,或者如果您使用的是任何其他构建工具,则可以添加任务(或等效任务)以将文件内容从不同的文件复制到实际文件取决于一些外部 system/environmental 变量。

使用 Spring Profile,您可以根据活动配置文件启动实体管理器 bean,该配置文件将引用您环境的 persistence.xml,例如 dev-persistence.xml, test-persisitence.xml, prod-persistence.xml。您可以使用 web.xml 设置活动配置文件。大多数情况下,web.xml 不会发生太大变化,因此您可以将 web.xml 保留在您的存储库中,并为该环境设置 spring 配置文件处于活动状态 属性。

在您的应用程序 WAR/EAR 包中包含特定于环境的信息确实是一个 BAAAAAAD 想法(通过包含多个配置,或者为不同的环境创建不同的包)。比如不同的数据库,应该在容器中维护。

在您的情况下,您的 persistence.xml 应该如下所示:

<persistence>
   <persistence-unit name="PU">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <jta-data-source>jdbc/fooAppDs</jta-data-source>
      <properties>
         ... ...
      </properties>
   </persistence-unit>
</persistence>

当然你应该有相应的资源参考 jdbc/fooAppDs.

通过这样做,您可以在任何环境中部署您的应用程序。您只需要在容器中创建正确的数据源并将其分配给 jdbc/fooAppDs.


另一种我认为可行的方法是在类路径中创建 hibernate.cfg.xml,但我不推荐。您可能希望拥有一个本地文件系统位置并将其添加到类路径中,而不是将文件放入您的 JAR/WAR/EAR.

我们曾经在不同的文件中为每个环境(例如 DEV、QA、PROD、UAT 等)维护 属性 个文件,并在构建期间复制其中一个。

蚂蚁搭建

<property environment="env" /> 
                <!-- ***** COMMAND LINE ARGUMENTS DEMOED HERE -->
                <property name="build_type" value= "${env.build_type}"/>

<copy todir="deploy">
    <fileset dir="src_dir"/>
    <globmapper from=${env.build_type}".persistence.xml" to="persistence.xml"/>
 </copy>

运行 像这样建造

ant -Denv.build_type=PROD

这会将 PROD.persistence.xml 复制到 persistence.xml

ant -Denv.build_type=DEV

这会将 DEV.persistence.xml 复制到 persistence.xml

您可以按以下方式配置您的 spring-config.xml 文件

  1. MYSQL
<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/kaya_db" />
    <property name="username" value="root" />
    <property name="password" value="nxtlife" />
</bean>
<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="packagesToScan" value="com.nxtlife.model" />
    <property name="hibernateProperties">

        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>
</bean>
<bean id="transactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager"
    p:sessionFactory-ref="sessionFactory">
</bean>

2.Similar for other database like oracle,postgre with different name of datasource,sessionfactory and transactionmanager. 3. Finally you can get object of session factory using following sessionfactory name

@Modifier("sessionfactoryname")
@Autowired
private SessionFactory obj;

不同数据库相似