【问题标题】:is there a standard way to define a JDBC Datasource for Java EE containers?是否有为 Java EE 容器定义 JDBC 数据源的标准方法?
【发布时间】:2025-12-02 11:10:02
【问题描述】:

我知道对于 JBoss,您需要一个位于相应实例的 /deploy 子目录中的 [name]-ds.xml 文件。 我对其他 Java EE 容器没有任何经验,但我试图尽可能地遵守标准。 是否有定义 JDBC 数据源并部署它的标准方法?如果可能的话,我想在 *.ear 文件中包含我的数据源(例如,用于演示目的的嵌入式内存 HSQLDB 数据源)?

如果没有标准方式,其他容器至少会接受jboss方式吗? (/deploy/*-ds.xml)

【问题讨论】:

    标签: java jdbc jakarta-ee hsqldb


    【解决方案1】:

    是否有标准的方法来定义和部署 JDBC 数据源?

    是的,有。这是通过<data-source> 元素完成的,您可以将其放入web.xmlejb-jar.xmlapplication.xml。如果你不喜欢 XML,你也可以使用注解来代替:@DataSourceDefinition

    web.xml 条目示例

    <data-source>
        <name>java:app/myDS</name>
        <class-name>org.postgresql.xa.PGXADataSource</class-name>
        <server-name>pg.myserver.com</server-name>
        <database-name>my_db</database-name>
        <user>foo</user>
        <password>bla</password>
        <transactional>true</transactional>
        <isolation-level>TRANSACTION_READ_COMMITTED</isolation-level>
        <initial-pool-size>2</initial-pool-size>
        <max-pool-size>10</max-pool-size>
        <min-pool-size>5</min-pool-size>
        <max-statements>0</max-statements>
    </data-source>
    

    进一步阅读:

    附注我很惊讶所有其他答案都说这不存在,虽然它显然存在,即使在最初提出这个问题时也是如此。

    【讨论】:

    • @SeanOwen >The question was about container-specific config, I believe - 我认为 Op 要求提供一种标准方式来处理原本可以通过特定于容器的配置来完成的事情。我同意当时这种机制只有几个月的历史,各个供应商并没有真正对此大肆宣传。
    • @radai 不客气!请注意,我发布了 java.net/jira/browse/JAVAEE_SPEC-19 以解决 web.xml 中数据源的可配置性问题。如果您或其他任何人对此感兴趣,请给它投票;)
    • @Gilberto EE.5.18.3(第 132 页)的 EE 平台规范,您可以在此处下载:download.oracle.com/otndocs/jcp/java_ee-7-fr-eval-spec/…
    • 这似乎不是官方的。您提供的链接来自一些博客,谷歌找不到其他任何东西。有这方面的一些参考文件吗?特别是web.xml 方法列出了所有可用的&lt;data-source&gt; 元素及其语义/可能值?
    • @MarcusJuniusBrutus 您可以在此处找到参考:download.oracle.com/otndocs/jcp/java_ee-7-fr-eval-spec/… 参见 EE.5.18.3(第 132 页)。这是官方的;)
    【解决方案2】:

    是否有标准的方式来定义和部署 JDBC 数据源?

    不,这是特定于容器的。作为Application Component Provider,您应该记录您需要的资源,Application deployer and Administrator 将配置它们。

    如果没有标准的方式,其他容器至少会接受JBoss的方式吗?

    不,因为这是 JBoss 方式,因此是特定于 JBoss 的。

    • 对于 Tomcat,您必须使用 context.xml 文件。
    • 使用码头,jetty-env.xml
    • 使用 WebSphere,您可以创建一个所谓的WebSphere Enhanced EAR
    • 使用 WebLogic,您可以将 JDBC Module 打包到您的应用程序中。
    • 使用 GlassFish,您可以使用命令 asadmin add-resources my.xml 添加 XML 文件中描述的数据源(例如 here)。
    • 等等等等

    请注意,有些项目试图以通用方式实现此目标,例如 jndi-resourcesCargo。还有更复杂的解决方案,如ControlTierChef

    现在,在您的情况下(据我了解,您希望使用将与您的应用程序捆绑在一起的嵌入式数据库),我认为您不应该在应用程序服务器级别配置数据源。您应该使用独立的连接池(如 c3p0 或 DBCP)将数据库的 jar 打包到应用程序中。

    【讨论】:

    • >这是特定于容器的。 - 不,它不一定是特定于容器的。还有一种标准方法是使用 &lt;data-source&gt; 元素,例如web.xml(见下面我的回答)。
    • 根据接受的答案,它似乎不是特定于容器的。
    • ...虽然可能在您回答问题时,它是特定于容器的。
    【解决方案3】:

    Sun 的 Java EE 理念定义了企业应用程序的设计、开发和部署中的多个角色。 Java EE 设计适应并反映了这些关注点分离。

    特别是 Sun 希望将开发人员与应用程序的管理员分开,这是一个好主意。开发人员以与容器无关的方式编写企业组件。例如,在 web.xml 中,您确实以标准方式声明数据源:

    <resource-ref>
     <res-ref-name>jdbc/myDB</res-ref-name>
     <res-type>javax.sql.DataSource</res-type>
     <res-auth>Container</res-auth>
    </resource-ref>
    

    这表示“应用程序需要的这个数据库,通过标准 JNDI 在 'jdbc/myDB' 提供给我,无论数据库是什么,无论你在什么容器中运行它”。这是开发人员所能做的——其余的必然是特定于容器的,因此不是标准化的。

    然后“myDB”的实际配置方式取决于另一个角色,即容器的管理员。

    所以我重复上面的正确答案:不。但原因是,否则,您将在特定主机和端口上将应用程序编码为特定类型的数据库,关键是您不应该这样做,因此没有标准支持目的。

    【讨论】:

    • 虽然您对一般情况是正确的,但在我的情况下,我计划使用 in-jvm、内存中的 DB,并在顶部使用 hibernate(将其视为对象缓存) - 我曾经是希望能以便携的方式完成
    • > 这是个好主意 - 对于某些用例来说这是个好主意,但不适用于所有用例。 Java EE 6 开始提供替代方案(例如,您可以在应用程序中定义数据源),而 Java EE 7 延续了这一趋势(也可以从应用程序中定义 JMS 目标和邮件会话等内容)。
    • >你不应该这样做 - 规范不应该要求一种唯一的工作方式。这种解释完全没有考虑到本地、私有(可能在内存中)数据库的存在,并且它没有缩小到最简单的应用程序。业务逻辑的接口和单独的模块可能是某些用例的最佳实践,但强制执行它使 EJB 感觉很重。从 Java EE 6 开始,选择权取决于开发人员(接口和单独的 EJB 模块现在是可选的)。
    • 嵌入式数据源的其他原因:敏捷团队、devops、云部署、单元和集成测试、教程和演示......列表无穷无尽......
    • 我在这里更多地只是描述了 Sun 的基本原理,现在确实感觉有些过时了。关注点分离仍然是一个好主意,并且不会阻止您在更高级别打包单独的关注点。至于它是否值得麻烦——对于一个大应用程序来说可能仍然是肯定的,对于小型库和小型依赖项来说可能不是。 JavaEE 几乎不会按比例缩小,是的。该规范必须强制要求一个连贯的架构和工作方式,我不同意它不应该,但它肯定可能不适合所有用例。