当前位置: 首页 > 知识库问答 >
问题:

应该在server.xml或context.xml中设置数据库连接属性吗

冯星阑
2023-03-14

我正在尝试为Spring web应用程序使用JNDI设置数据库连接属性。

我正在考虑以下两种方法:

在您的Spring配置中,您可能有如下内容:

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/facs"/>

那么在webapp/meta-inf/context.xml文件中也应该有类似的内容:

<?xml version='1.0' encoding='utf-8'?>

<!-- antiResourceLocking="true" -->
<Context path="/podd-apn"
         reloadable="true"
         cachingAllowed="false"
         antiResourceLocking="true"
         >

  <Resource name="jdbc/facs"              
            type="javax.sql.DataSource" username="${database.username}" password="${database.password}"
            driverClassName="org.postgresql.Driver" 
            url="${database.url}"
            maxActive="8" maxIdle="4"
            global="jdbc/facs" 
            />


</Context>

在您的web.xml中应该有如下内容:

<!-- JNDI -->
  <resource-ref>
    <description>FACs Datasource</description>
    <res-ref-name>jdbc/facs</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref> 
<jee:jndi-lookup id="dbDataSource"
   jndi-name="jdbc/DatabaseName"
   expected-type="javax.sql.DataSource" />
<GlobalNamingResources>
  <Resource name="jdbc/DatabaseName" auth="Container" type="javax.sql.DataSource"
              username="dbUsername" password="dbPasswd"
              url="jdbc:postgresql://localhost/dbname"
              driverClassName="org.postgresql.Driver"
              initialSize="5" maxWait="5000"
              maxActive="120" maxIdle="5"
              validationQuery="select 1"
              poolPreparedStatements="true"/>
</GlobalNamingResources/>

并引用Tomcat的web context.xml中的JNDI资源,如下所示:

<ResourceLink name="jdbc/DatabaseName"
   global="jdbc/DatabaseName"
   type="javax.sql.DataSource"/>


我的问题是哪里是保存数据库属性的最佳位置?它们应该放在server.xml中还是放在context.xml中?

另外,如果我有两个数据库,我应该使用两个配置吗?

此外,直接将它们放置在server.xml或context.xml中是否是最佳实践?还是需要通过Tomcat Manager GUI控制台进行配置?

谢谢!

共有1个答案

谢鸿羲
2023-03-14

我更喜欢第三种方法,它从user1016403描述的方法1和方法2中吸取了最好的东西。

  1. 保存server.xml
  2. 上的数据库属性
  3. 从web应用程序meta-inf/context.xml
  4. 中引用 server.xml数据库属性

第一点对于安全原因是有用的,第二点对于从web应用程序引用服务器属性值是有用的,即使服务器属性值会更改。

此外,将服务器上的资源定义与web应用程序的使用分离使得这种配置可以跨具有不同复杂性的组织进行扩展,其中不同的团队在不同的层/层上工作:如果管理员与开发人员共享每个资源的相同JNDI名称,则服务器管理员团队可以在不与开发人员团队冲突的情况下工作。

定义JNDI名称jdbc/applicationcontext_databasename

<GlobalNamingResources>
  <Resource name="jdbc/ApplicationContext_DatabaseName" auth="Container" type="javax.sql.DataSource"
              username="dbUsername" password="dbPasswd"
              url="jdbc:postgresql://localhost/dbname"
              driverClassName="org.postgresql.Driver"
              initialSize="5" maxWait="5000"
              maxActive="120" maxIdle="5"
              validationQuery="select 1"
              poolPreparedStatements="true"/>
</GlobalNamingResources/>

通过name属性中指定的应用程序专用JNDI上下文java:comp/env/从web应用程序meta-inf/context.xml链接jdbc/applicationcontext_databaseName的属性:

<Context path="/ApplicationContext" ... >
  <!--
    "global" attribute links to GlobalNamingResources in the ${catalina.base}/conf/server.xml (server administrator team)
    "name" attribute is relative to the application-private JNDI context java:comp/env/ and is looked up from the java web application (application developer team)
  -->
  <ResourceLink global="jdbc/ApplicationContext_DatabaseName" name="jdbc/DatabaseName" type="javax.sql.DataSource"/>
</Context>

最后,为了使用JNDI资源,在web应用程序的部署描述符中指定JNDI名称jdbc/databasename:

<resource-ref>
    <description>DatabaseName's Datasource</description>
    <res-ref-name>jdbc/DatabaseName</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref> 

在Spring上下文中:

<jee:jndi-lookup id="DatabaseNameDataSource"
   jndi-name="jdbc/DatabaseName"
   expected-type="javax.sql.DataSource" />

一个web应用程序使用的多个数据源

只需向Tomcat的server.xml添加配置:

<GlobalNamingResources>
  <Resource name="jdbc/ApplicationContext_DatabaseName1" ... />
  <Resource name="jdbc/ApplicationContext_DatabaseName2" ... />
  ...
</GlobalNamingResources/>

通过name属性中指定的application-private JNDI上下文java:comp/env/添加链接web applicationmeta-inf/context.xml

<Context path="/ApplicationContext" ... >
  <ResourceLink global="jdbc/ApplicationContext_DatabaseName1" name="jdbc/DatabaseName1" ... />
  <ResourceLink global="jdbc/ApplicationContext_DatabaseName2" name="jdbc/DatabaseName2" ... />
  ...
</Context>
<resource-ref>
    <description>DatabaseName1's Datasource</description>
    <res-ref-name>jdbc/DatabaseName1</res-ref-name> ... 
</resource-ref> 
<resource-ref>
    <description>DatabaseName2's Datasource</description>
    <res-ref-name>jdbc/DatabaseName2</res-ref-name> ... 
</resource-ref>
...
<jee:jndi-lookup id="DatabaseName1DataSource"
   jndi-name="jdbc/DatabaseName1" ... />
<jee:jndi-lookup id="DatabaseName2DataSource"
   jndi-name="jdbc/DatabaseName2" ... />
...


同一服务器上多个web应用程序使用的多个数据源

只需将配置添加到Tomcat的server.xml中:

<GlobalNamingResources>
  <Resource name="jdbc/ApplicationContextX_DatabaseName1" ... />
  <Resource name="jdbc/ApplicationContextX_DatabaseName2" ... />
  <Resource name="jdbc/ApplicationContextY_DatabaseName1" ... />
  <Resource name="jdbc/ApplicationContextY_DatabaseName2" ... />
  ...
</GlobalNamingResources/>

其他配置应该可以从以前的变型情况中推断出来。


多个数据源到同一服务器上的多个web应用程序使用的同一数据库

在这种情况下,Tomcat的server.xml配置如下:

<GlobalNamingResources>
  <Resource name="jdbc/ApplicationContextX_DatabaseName" ... />
  <Resource name="jdbc/ApplicationContextY_DatabaseName" ... />

最终出现在两个不同的web应用程序meta-inf/context.xml中,类似于:

<Context path="/ApplicationContextX" ... >
  <ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>

并且喜欢:

<Context path="/ApplicationContextY" ... >
  <ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>

因此,有人可能担心部署在同一服务器上的两个不同应用程序查找并使用相同的name=“jdbc/databaseName”:这不是问题,因为jdbc/databaseName是应用程序专用的JNDI上下文java:comp/env/,因此使用java:comp/env/applicationcontextx无法(按设计)查找链接到global=“jdbc/applicationcontexty_databaseName”

当然,如果您觉得没有这种担心更轻松,您可以使用不同的命名策略,例如:

<Context path="/ApplicationContextX" ... >
  <ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/applicationXprivateDatabaseName" ... />
</Context>

并且喜欢:

<Context path="/ApplicationContextY" ... >
  <ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/applicationYprivateDatabaseName" ... />
</Context>
 类似资料:
  • 问题内容: 我正在尝试使用JNDI为Spring Web应用程序设置数据库连接属性。 我正在考虑以下两种方法: 方法1: 在你的Spring配置中,你可能会有类似以下内容: 然后,在你的webapp /META-INF/context.xml文件中,你也应该具有类似的内容: 在你的web.xml中,你应该像这样: 方法二: 在Spring上下文中这样设置: 你可以使用类似下面的命令在Tomcat的

  • 问题内容: 要指定SQLite连接属性,请使用org.sqlite.SQLiteConfig,它的内容如下: 使用c3p0创建连接池的过程如下: 问题:如何创建结合了两者的数据源,让我设置诸如连接池的最大池大小和sqlite的同步模式之类的东西? 问题答案: 尝试 现在,数据源将是c3p0 PooledDataSource,它包装了已根据需要配置的SQLite未池化数据源。 请参阅C3P0的文档,

  • 问题内容: 用Java创建单例的最佳方法是什么?数据库连接是否应该是单例连接(单例连接是自动线程安全的)?因为理论上数据库不能被许多用户同时访问。 问题答案: 数据库连接通常不应为单例。 两个原因: 许多数据库驱动程序不是线程安全的。使用单例意味着如果您有多个线程,它们将共享同一连接。单例模式不会给您带来安全感。它仅允许许多线程轻松共享“全局”实例。 就我个人而言,我认为Singleton通常会导

  • 问题内容: 我们有一个JPA应用程序(使用hibernate),我们需要将调用传递给需要JDBC数据库连接作为参数的旧式报告工具。有没有一种简单的方法可以访问hibernate已设置的JDBC连接? 问题答案: 您想在哪里获得该连接尚不清楚。一种可能是从.NET 使用的基础Hibernate中获取它。使用JPA 1.0,您必须执行以下操作: 请注意,该方法不是可移植的,此方法的结果特定于实现:上面

  • 问题内容: 我并不像php开发人员,但我必须使用它,而且我不太了解PHP在会话期间如何处理内存分配。 我正在开发一个要求进行HTTP身份验证的应用程序,一旦登录,便可以通过一个漂亮的界面来操作数据。 有人在另一篇文章中告诉我,我不应该在每次执行后关闭mysql数据连接,但是我不知道在使用此应用程序期间该连接如何保持内存,因为在服务器端我不知道PHP保留了什么内容记忆与否。 所以我的问题是我应该使用

  • 我有一个多租户Flask Web应用程序,它与1个主MySQL数据库(用于查找客户端信息)和几十个客户端MySQL数据库(都具有相同的模式)接口。 我目前正尝试使用SQLAlchemy和Flask SQLAlchemy扩展与数据库接口,但我正在努力找到一种方法,允许我在应用程序中定义的模型根据客户机的不同,动态地将上下文从一个客户机数据库切换到另一个客户机数据库。 在Flask-SQLAlChem