在持久化配置文件 persistence.xml 和 Spring 配置文件中配置数据源的区别

37

我看过(也做过)两种数据源配置的方法(下面的代码仅供演示):

1)在持久化单元内部进行配置,例如:

<persistence-unit name="LocalDB" transaction-type="RESOURCE_LOCAL">
    <class>domain.User</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
        <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost"/>
        <property name="hibernate.hbm2ddl.auto" value="create"/>
        <property name="hibernate.c3p0.min_size" value="5"/>
        ....
        <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
    </properties>
</persistence-unit>

2)在Spring配置文件(例如applicationContext.xml)中的配置:

<bean id="domainEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="JiraManager"/>
    <property name="dataSource" ref="domainDataSource"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="generateDdl" value="false"/>
            <property name="showSql" value="false"/>
            <property name="databasePlatform" value="${hibernate.dialect}"/>
        </bean>
    </property>
</bean>

<bean id="domainDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${db.driver}" />
    <property name="jdbcUrl" value="${datasource.url}" />
    <property name="user" value="${datasource.username}" />
    <property name="password" value="${datasource.password}" />
    <property name="initialPoolSize" value="5"/>
    <property name="minPoolSize" value="5"/>
    .....
</bean>

问题是:每种方法都有哪些优点和缺点,或者说这只是个人口味的问题?


再次思考了一下你的问题:难道你实际上更想知道“Spring有什么优势吗?”这样听起来好像你并没有看到它的价值。问问自己:为什么要使用它? - BalusC
@BalusC:我不知道这些配置是如何在启动时转换为entityManagerFactory的。如果是同样的事情,那么回答我的问题就是“这只是个人口味问题”。如果有什么不同的地方,那么我想知道其中的区别。 - Roman
我不会把使用Spring称为“品味问题”。你使用它是有原因的:IoC。实际上,我曾经发布过一个答案,大意是“如果你正在使用Spring和/或需要IoC(这是Spring的工作),那么就选择Spring,否则只需使用‘普通’的JPA。”但是在仔细思考了你的问题后,我删除了这个答案,因为实际问题似乎比这更深入。 - BalusC
我不使用Spring :) 如果我在使用它,我会让Spring进行管理。这样你就可以利用它的IoC功能。但是,我想知道你是否已经考虑过这个问题,我只是不想表现得像明显先生一样。 顺便说一句:删除的答案对于10K+可见,无论如何也无法恢复。 - BalusC
这没什么特别的。我已经完全、逐字地复制在第2个评论里了。 - BalusC
显示剩余2条评论
2个回答

32

如果你使用JavaEE容器,那将会有很大的不同。

与个人偏好不同,如果你遵循第二种方法并进行一些修改,那么你会得到更好的结果。

在第一种情况下,你需要创建自己的连接池,而且不能从容器中现有的连接池中获益。因此,即使你将容器配置为最多只有20个与数据库的同时连接,但由于这个新的连接池不受限于你的配置,所以你无法保证这个最大值。而且,你也无法获得任何容器提供的监控工具的优势

在第二种情况下,你同样需要创建自己的连接池,带有以上相同的缺点。但是,你可以隔离这个Spring bean的定义,并仅在测试运行中使用它。

最好的方法是通过JNDI查找容器的连接池。然后,你可以确保遵守容器的数据源配置。

在运行测试时请使用此方法。

<!-- datasource-test.xml -->
<bean id="domainDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
   <property name="driverClass" value="${db.driver}" />
   <property name="jdbcUrl" value="${datasource.url}" />
   <property name="user" value="${datasource.username}" />
   <property name="password" value="${datasource.password}" />
   <property name="initialPoolSize" value="5"/>
   <property name="minPoolSize" value="5"/>
.....
</bean>

在部署到JavaEE容器时使用此选项

<!-- datasource.xml -->
<jee:jndi-lookup id="domainDataSource" jndi-lookup="jndi/MyDataSource" />
  • 记得设置JEE模式
  • 尽管Tomcat不是完整的JavaEE容器,但它通过JNDI管理数据源,因此这个答案仍然适用。

谢谢!好观点!我长期以来只使用Tomcat,但是我的当前项目部署在Glassfish上,你的建议为什么要这样做解释了一些事情。 - Roman

4

这完全取决于个人偏好。

如果您已经在使用Spring,我建议您使用它的配置。它的目的是依赖注入和管理,因此让它针对您对数据库的依赖来完成其工作。但是,如果您还没有使用Spring,请继续使用持久化配置,因为这将使您的项目更简单而又实用。不过,我建议任何需要使用Hibernate与数据库交互的项目都足够大,可以使用Spring框架。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接