Надлежащее использование Пула соединения JDBC (Glassfish)

Мне нужно соединение с базой данных в веб-сервисе Java, реализованном как боб сессии, и я не уверен, делаю ли я его правильно.

Я создал класс

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

Каждый раз, когда мне нужно соединение, я делаю

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

         }
     }
 }

Это в порядке для использования его этот путь или я, DataSource должен быть членом боба?

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

Я сожалею, если это - nube вопрос, но я довольно плохо знаком с Java. Заранее спасибо.

9
задан BalusC 16 December 2009 в 17:09
поделиться

2 ответа

Помимо форматирования в стиле 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();             
    }
}

Я добавляю сюда ExceptionInInitializerError , чтобы приложение немедленно остановилось, и вам не придется сталкиваться с "необъяснимым" NullPointerException при попытке установить соединение.

15
ответ дан 4 December 2019 в 08:33
поделиться

В древнем мире 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;
    }
}

Чтобы использовать его, просто назовите его так:

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

Но это было до эры EJB3 и внедрения зависимостей. Теперь, при использовании EJB3, если вы настроили свой DataSource в своем контейнере EJB, все, что вам нужно сделать для автоматического внедрения DataSource в ваш Stateless Bean, - это написать (где mydatabase - имя источника данных):

@Resource
private DataSource mydatabase;

Используйте атрибут name, если вы хотите явно, ну, установить имя:

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

EJB3 фактически делает ServiceLocator , и вам действительно следует предпочесть инъекцию при работе с ними.

10
ответ дан 4 December 2019 в 08:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: