正确使用JDBC连接池(Glassfish)

a1e*_*x07 9 java jndi jdbc glassfish java-ee

我需要在作为会话bean实现的Java Web服务中建立数据库连接,我不确定我是否做得对.

我创建了一个类

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();             
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

         }
     }
 }
Run Code Online (Sandbox Code Playgroud)

以这种方式使用它是否可以,或者我DataSource必须是bean的成员?

  @Stateless  
  @WebService  
  public class TestBean  {  
   private @Resource(name=dbName) DataSource m_ds;   
  }  
Run Code Online (Sandbox Code Playgroud)

如果这是一个nube问题,我很抱歉,但我对Java很新.提前致谢.

Bal*_*usC 15

除了C风格的格式化,一些不必要的行和有点差的异常处理,你可以这样做.

这是我如何做到的:

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();             
    }
}
Run Code Online (Sandbox Code Playgroud)

我扔到这里,ExceptionInInitializerError以便应用程序将立即停止,以便您NullPointerException在尝试获取连接时不需要面对"无法解释的" .

  • 然而,我会赞成在bean本身注入,因为它更容易模拟和测试. (2认同)

Pas*_*ent 10

在古代J2EE世界中,传统的管理方法是使用a 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

DataSource ds = ServiceLocator.getInstance().getDataSource("jdbc/mydatabase");
Run Code Online (Sandbox Code Playgroud)

但这是在EJB3和依赖注入时代之前.现在,在使用EJB3时,如果已经DataSource在EJB容器中设置了自己,那么DataSource在无状态Bean中自动注入的所有工作就是编写(mydatabase数据源的名称在哪里):

@Resource
private DataSource mydatabase;
Run Code Online (Sandbox Code Playgroud)

如果要显式地使用name属性,请设置名称:

@Resource(name="jdbc/mydatabase")
private DataSource dataSource;
Run Code Online (Sandbox Code Playgroud)

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

  • 啊,drat,我知道*它.这确实比一些帮手类好****.+1. (2认同)