Правильное использование JDBC Connection Pool (Glassfish) - PullRequest
10 голосов
/ 16 декабря 2009

Мне нужно соединение с базой данных в веб-сервисе 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;   
  }  

Извините, если это сложный вопрос, но я довольно новичок в Java. Заранее спасибо.

Ответы [ 3 ]

15 голосов
/ 16 декабря 2009

Помимо форматирования в стиле 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 при попытке установить соединение.

10 голосов
/ 17 декабря 2009

В древнем мире 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 и Dependency Injection. Теперь при использовании EJB3, если вы настроили DataSource в своем контейнере EJB, все, что вам нужно сделать, чтобы автоматически внедрить DataSource в ваш компонент без сохранения состояния, это написать (где mydatabase название источника данных):

@Resource
private DataSource mydatabase;

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

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

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

0 голосов
/ 08 февраля 2013

Хм, разве это не пример JDBC DataSource , а не Glassfish Connection Pool ?

...