Java 在Tomcat中调用JNDI数据源的正确方法

Java 在Tomcat中调用JNDI数据源的正确方法,java,tomcat,datasource,jndi,Java,Tomcat,Datasource,Jndi,我正在Tomcat服务器上使用Java web应用程序,想知道从Tomcat的JNDI中访问数据库连接的“最佳实践”是什么 目前,每当我需要访问数据库时,基本上就是这样做的: Context envContext = null; DataSource dataSource = null; try { envContext = (Context)ctx.lookup("java:/comp/env"); dataSource = (DataSource)envContext.lo

我正在Tomcat服务器上使用Java web应用程序,想知道从Tomcat的JNDI中访问数据库连接的“最佳实践”是什么

目前,每当我需要访问数据库时,基本上就是这样做的:

Context envContext = null;
DataSource dataSource = null;
try {
    envContext  = (Context)ctx.lookup("java:/comp/env");
    dataSource = (DataSource)envContext.lookup("jdbc/datasource");
    return dataSource.getConnection();
} catch (Exception e){
    e.printStackTrace();
    return null;
}finally {
    if(envContext != null){
        try{
           envContext.close();
        } catch (NamingException e){
            e.printStackTrace();
        }
    }
}

但是,每次我想访问数据库时,这是从JNDI查找连接的正确方法吗?我应该保留对上下文或数据源的引用吗?

您的查找代码看起来正常
在您的问题上下文中,只要您不缓存实际的连接对象,缓存数据源就可以了。


不过,我已经有一段时间没有使用这种方法了。现在,我至少使用spring注入数据源/初始化JdbcTemplate

您也可以这样做:-

...

Context initContext = new InitialContext();
DataSource dataSource = (DataSource) initContext.lookup("java:comp/env/jdbc/datasource");

...

jndi查找本质上是映射查找,因此其开销最小。但最好只获取一次数据源并“缓存”它。因此,如果有什么需要的话——编写一个返回数据源的方法是理想的,这样就不会将太多的代码绑定到J2EE内部并使代码更易于测试。

new InitialContext()
在每个应用程序容器中都很昂贵,它应该是一个
静态final
并在
静态{}
块中创建,有效地使其成为一个
单例
。您只需创建此引用一次,并在任何需要的地方重复使用它


数据源
也应该是一个
静态
。您应该有一个
公共静态连接getConnection()方法检索
连接
对象,代码不应该直接处理
数据源
。这在
PooledDataSource
实现中尤其有效。

是的,通常我只会使用一些第三方实用程序,比如hibernate,但为此,除了纯java之外,我不允许使用任何东西。这正是我想要的答案,谢谢。另一个问题是,每次我进行数据访问时,创建新上下文的开销是否很大?相对而言,我不这么认为。但是如果你每次都对它进行标记并创建一个上下文,而不是仅仅缓存数据源,我怀疑你会看到不同。但实际上,与处理请求的其他活动相比,获得数据源(或上下文)的次数是最少的。JNDI查找并不昂贵,
InitialContext
查找在每个应用程序容器中都非常昂贵,应该在应用程序启动时只执行一次。大多数人不知道这两者的区别。为什么它很贵?它不需要做很多事情,特别是它不需要做任何网络I/O?我怀疑这是城市神话。@EJP不是城市神话,我有一份合同,其中一名“首席”开发人员(一名VB人员)正在编写servlet,他在每次请求时都创建
new InitialContext()
。每个请求都花了将近一分钟的时间。他抱怨Java有多慢,等等,等等。我检查了他的代码,把那一行移到了一个
私人静态决赛
,然后砰的一声。请求在
数百毫秒范围内。这是WebLogic的一个非常早期的版本,因为摩尔定律,所以现在可能不会那么糟糕。但当我在2011年3月写下这个答案时,这是一个重复的问题。你还没有回答我的问题。为什么这么贵?还有,引用另一个地方的话。您是否实际测试了“每个应用程序容器”?没有这些,你的答案是毫无根据的。那么“
new InitialContext()
是昂贵的”这句话与您上面的评论“
InitialContext
查找是非常昂贵的”有什么关系呢?下定决心吧。