Java JDBC连接池(Glassfish)的正确使用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1915992/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 23:52:36  来源:igfitidea点击:

Proper usage of JDBC Connection Pool (Glassfish)

javajdbcjakarta-eeglassfishjndi

提问by a1ex07

I need a database connection in Java Web service implemented as a session bean, and I'm not sure if I do it right.

我需要一个作为会话 bean 实现的 Java Web 服务中的数据库连接,但我不确定我是否做得对。

I created a class

我创建了一个类

public final class SQLUtils   {  
    //.....  
    private static DataSource  m_ds=null;    

    static  
    {  
        try
        {
            InitialContext ic = new InitialContext();
            m_ds = (DataSource) ic.lookup(dbName); //Connection pool and jdbc resource previously created in Glassfish  , dbName contains the proper JNDI resource name 

        }
        catch (Exception e)
        {
            e.printStackTrace();
            m_ds = null;
        }

    }

    public static Connection getSQLConnection() throws SQLException  
    {  
        return m_ds.getConnection();             
    }
}

Whenever I need a connection I do

每当我需要连接时,我都会这样做

 Connection cn = null;  
 try  
 {
     cn = SQLUtils.getSQLConnection();
     // use connection
 }
 finally 
 {
     if (null != cn)
     {
         try
         {
             cn.close();
         }
         catch (SQLException e)
         {

         }
     }
 }

Is it ok to use it this way, or I DataSource must be a member of the bean ?

可以这样使用它,还是我 DataSource 必须是 bean 的成员?

  @Stateless  
  @WebService  
  public class TestBean  {  
   private @Resource(name=dbName) DataSource m_ds;   
  }  

I'm sorry if it is a nube question, but I'm pretty new to Java. Thanks in advance.

如果这是一个 nube 问题,我很抱歉,但我对 Java 还很陌生。提前致谢。

采纳答案by BalusC

Apart from the C-style formatting, a few unnecessary lines and a bit poor exception handling, you can just do so.

除了 C 风格的格式、一些不必要的行和有点糟糕的异常处理之外,你可以这样做。

Here's how I'd do it:

这是我的做法:

public final class SQLUtil {
    private static DataSource dataSource;
    // ..

    static {
        try {
            dataSource = (DataSource) new InitialContext().lookup(name);
        } catch (NamingException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    public static Connection getConnection() throws SQLException {  
        return dataSource.getConnection();             
    }
}

I throw here ExceptionInInitializerErrorso that the application will immediately stop so that you don't need to face "unexplainable" NullPointerExceptionwhen trying to obtain a connection.

我扔在这里ExceptionInInitializerError是为了让应用程序立即停止,这样您NullPointerException在尝试获取连接时就不需要面对“无法解释的”问题。

回答by Pascal Thivent

In the ancient J2EE world, the traditional way to manage this was to use a ServiceLocator. Below, a sample implementation (non optimized, the DataSourcecould be cached):

在古老的 J2EE 世界中,管理它的传统方法是使用ServiceLocator. 下面是一个示例实现(未优化,DataSource可以缓存):

public class ServiceLocator {
    private Context initalContext;

    private static ServiceLocator ourInstance = new ServiceLocator();

    public static ServiceLocator getInstance() {
        return ourInstance;
    }

    private ServiceLocator() {
        try {
            this.initalContext = new InitialContext();
        } catch (NamingException ex) {
            throw new ServiceLocatorException(...);
        }
    }

    public DataSource getDataSource(String dataSourceName) {
        DataSource datasource = null;

        try {
            Context ctx = (Context) initalContext.lookup("java:comp/env");
            datasource = (DataSource) ctx.lookup(dataSourceName);
        } catch (NamingException ex) {
            throw new ServiceLocatorException(...);
        }

        return datasource;
    }
}

To use it, simply call it like this:

要使用它,只需像这样调用它:

DataSource ds = ServiceLocator.getInstance().getDataSource("jdbc/mydatabase");

But this was prior to the EJB3 and Dependency Injection era. Now, when using EJB3, if you have setup your DataSourcein your EJB container, all you have to do to automatically inject the DataSourcein your Stateless Bean is to write(where mydatabaseis the name of the datasource):

但这是在 EJB3 和依赖注入时代之前。现在,当使用 EJB3 时,如果你已经DataSource在你的 EJB 容器中设置了你的,你需要做的就是DataSource在你的无状态 Bean 中自动注入它(其中mydatabase是数据源的名称):

@Resource
private DataSource mydatabase;

Use the name attribute if you want to explicitly, well, set the name:

如果您想明确设置名称,请使用 name 属性:

@Resource(name="jdbc/mydatabase")
private DataSource dataSource;

EJB3 actually make the ServiceLocatorpattern obsolete and you should really prefer injection when working with them.

EJB3 实际上使ServiceLocator模式过时了,在使用它们时您应该更喜欢注入。

回答by Per Lindberg

Um, isn't this an example to a JDBC DataSource, not a Glassfish Connection Pool?

嗯,这不是JDBC DataSource的示例,而不是Glassfish 连接池吗?