2009-12-16 6 views
9

Ich brauche eine Datenbankverbindung im Java-Webdienst, die als Session-Bean implementiert ist, und ich bin mir nicht sicher, ob ich es richtig mache.Korrekte Verwendung des JDBC-Verbindungspools (Glassfish)

habe ich eine Klasse

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

Jedes Mal, wenn ich eine Verbindung benötige ich

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

     } 
    } 
} 

Ist es in Ordnung, es auf diese Weise zu verwenden, oder ich Datasource muss ein Mitglied der Bohne sein?

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

Es tut mir leid, wenn es eine nube Frage ist, aber ich bin ziemlich neu in Java. Danke im Voraus.

Antwort

14

Abgesehen von der C-Style-Formatierung, ein paar unnötige Zeilen und ein bisschen schlechte Ausnahmebehandlung können Sie dies tun.

Hier ist, wie ich es tun würde:

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

Ich werfe hier ExceptionInInitializerError, so dass die Anwendung sofort stoppt, so dass Sie brauchen, um NullPointerException nicht zu Gesicht „unerklärlich“, wenn eine Verbindung zu erhalten versuchen.

+1

+1 für die ExceptionInInitializerError, die ich nicht kannte. – ewernli

+2

Ich würde jedoch die Injektion in der Bohne selbst bevorzugen, weil es einfacher ist zu verspotten und zu testen. – ewernli

+0

Vielen Dank für Ihre Antwort. – a1ex07

10

In der alten J2EE-Welt war der traditionelle Weg, dies zu handhaben, die Verwendung eines ServiceLocator. Im Folgenden wird eine Beispielimplementierung (nicht optimiert, könnte die DataSource zwischengespeichert werden):

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

es zu benutzen, einfach es so nennen:

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

Aber das war vor der EJB3 und Dependency Injection Epoche. Wenn nun EJB3 verwenden, wenn Sie Setup Ihre DataSource in Ihrem EJB-Container haben, alles, was Sie tun müssen, um automatisch die DataSource in Ihrem Stateless Bean injizieren schreiben (wo mydatabase ist der Name der Datenquelle):

@Resource 
private DataSource mydatabase; 

das Namensattribut verwenden, wenn Sie ausdrücklich wollen, na ja, den Namen festgelegt: make tatsächlich

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

EJB3 die ServiceLocator Muster veraltet und Sie sollten wirklich Injektion bevorzugen, wenn sie mit ihnen zu arbeiten.

+2

Ah drat, ich * wusste * es. Das ist in der Tat ** viel besser als irgendeine Hilfsklasse. +1. – BalusC

0

Ähm, ist das nicht ein Beispiel an einen JDBC Datasource, keine Glassfish Connection Pool?

Verwandte Themen