当前位置: 首页 > 面试题库 >

在server.xml还是context.xml中设置数据库连接属性

诸俊才
2023-03-14
问题内容

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

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

方法1:

在你的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> 

方法二:

在Spring上下文中这样设置:

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

你可以使用类似下面的命令在Tomcat的server.xml中声明JNDI资源:

<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中?

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

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


问题答案:

我更喜欢第三种方法,该方法从 user1016403描述的方法1和方法2 中获得最大的收益。

方法3
1. 将数据库属性保存在 server.xml
2. server.xml从Web应用程序引用数据库属性META-INF/context.xml
方法3的好处
尽管出于安全原因第一点很有用,但第二点对于从Web应用程序引用服务器属性值也是有用的,即使服务器属性值会发生变化。


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

方法3的实施

定义JNDI名称jdbc/ApplicationContext_DatabaseName

使用类似这样的声明jdbc/ApplicationContext_DatabaseName在Tomcat的各种属性和值server.xml

<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/>

jdbc/ApplicationContext_DatabaseName通过属性META-INF/context.xmljava:comp/env/指定的应用程序专用JNDI上下文从网络应用程序链接的name属性:

<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资源,请jdbc/DatabaseName在Web应用程序的部署描述符中指定JNDI名称:

<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" />

方法3的缺点
如果JNDI名称被更改,则必须同时编辑和server.xml和,META-INF/context.xml并且必须进行部署。但是,这种情况很少见。

方法3的变化
一个Web应用程序使用的许多数据源

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

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

META-INF/context.xml通过属性中java:comp/env/指定的应用程序专用JNDI上下文添加链接Web应用程序name:

<Context path="/ApplicationContext" ... >
  <ResourceLink global="jdbc/ApplicationContext_DatabaseName1" name="jdbc/DatabaseName1" ... />
  <ResourceLink global="jdbc/ApplicationContext_DatabaseName2" name="jdbc/DatabaseName2" ... />
  ...
</Context>

最后,在Web应用程序的部署描述符中添加JNDI资源使用情况:

<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>
...

在Spring上下文中:

<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/,因此ApplicationContextX 使用java:comp/env/不能(根据设计)查找链接到的资源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>


 类似资料:
  • 我正在尝试为Spring web应用程序使用JNDI设置数据库连接属性。 我正在考虑以下两种方法: 在您的Spring配置中,您可能有如下内容: 那么在webapp/meta-inf/context.xml文件中也应该有类似的内容: 在您的web.xml中应该有如下内容: 并引用Tomcat的web context.xml中的JNDI资源,如下所示: 我的问题是哪里是保存数据库属性的最佳位置?它们

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

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

  • 我也使用了SQL和Oracle,但我有一个很大的困惑。在oracle中,用户属于数据库还是数据库属于用户。因为我已经使用sql命令在oracle中创建了一个新用户。然后我创建了表,但我没有创建任何数据库,那么新表去了哪里? 我猜想表与oracle中的用户相关联,就像创建表的人是表的所有者,其他用户无法访问该表,因此无需通过先创建数据库,然后在其下创建表来区分它们。 但是在MYSQL中(使用PhpM

  • 问题内容: 在PHP中使用单例而不是全局的数据库连接有什么好处?我觉得使用单例而不是全局会使代码变得不必要地复杂。 全局编码 用Singleton编码 如果除了全局或单例之外,还有一种更好的初始化数据库连接的方法,请提及它并描述它比全局或单例具有的优势。 问题答案: 我知道这很旧,但是Dr8k的答案 几乎 就在那里。 当您考虑编写一段代码时,假设它会改变。这并不意味着您要假设它会在将来的某个时刻对

  • 问题内容: 我想为Eclipselink中的每个会话设置一个数据库会话变量。我要执行的SQL是这样的: 如果我尝试创建一个将执行命令的SessionEvent侦听器,我似乎会陷入无限递归中。 我是用事件侦听器以错误的方式处理问题还是需要以特殊方式执行SQL命令? 问题答案: 您正在会话上执行查询,而会话仍在为其他进程获取连接。在事件结束之前,会话将无法使用触发postConnect事件的连接,这意