2009-12-16 17 views
9

Ho bisogno di una connessione al database nel servizio Web Java implementato come bean di sessione e non sono sicuro di farlo correttamente.Uso corretto del pool di connessione JDBC (Glassfish)

ho creato una classe

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();    
    } 
} 

Ogni volta che ho bisogno di una connessione che faccio

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

     } 
    } 
} 

E 'ok per usarlo in questo modo, o io DataSource deve essere un membro del chicco?

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

Mi dispiace se si tratta di una domanda di nuvola, ma sono piuttosto nuovo di Java. Grazie in anticipo.

risposta

14

Oltre alla formattazione in stile C, alcune righe non necessarie e una gestione delle eccezioni un po 'scadente, è sufficiente farlo.

Ecco come lo farei:

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();    
    } 
} 

Butto qui ExceptionInInitializerError in modo che l'applicazione si arresta immediatamente in modo che non c'è bisogno di affrontare "inspiegabile" NullPointerException quando si cerca di ottenere un collegamento.

+1

+1 per l'eccezione ExceptionInInitializerError che non conoscevo. – ewernli

+2

Preferirei comunque l'iniezione nel bean stesso perché è più facile deridere e testare. – ewernli

+0

Grazie mille per la risposta. – a1ex07

10

Nell'antico mondo J2EE, il modo tradizionale per gestirlo era utilizzare ServiceLocator. Qui di seguito, un esempio di implementazione (non ottimizzato, il DataSource potrebbe essere memorizzato nella cache):

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; 
    } 
} 

Per utilizzarlo, è sufficiente chiamare in questo modo:

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

Ma questo era prima della EJB3 e Dependency Injection era. Ora, quando si utilizza EJB3, se si dispone di installare il vostro DataSource nel vostro contenitore EJB, tutto quello che dovete fare per iniettare automaticamente il DataSource nel vostro Stateless Bean è quello di scrivere (dove mydatabase è il nome del datasource):

@Resource 
private DataSource mydatabase; 

utilizzare l'attributo nome se si desidera in modo esplicito, bene, impostare il nome:

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

EJB3 effettivamente fare il modello ServiceLocator obsoleta e si dovrebbe davvero preferisce iniezione quando si lavora con loro.

+2

Ah drat, io * lo sapevo *. Questo è davvero ** molto ** meglio di qualche classe di supporto. +1. – BalusC

0

Uhm, non è questo un esempio per un JDBC DataSource, non un Glassfish Connection Pool?

Problemi correlati