2009-09-22 4 views
25

После помощник мой класс, чтобы получить DB соединение:JDBC пула соединений с использованием C3P0

Я использовал пул соединений C3P0, как описано here.

public class DBConnection { 

    private static DataSource dataSource; 
    private static final String DRIVER_NAME; 
    private static final String URL; 
    private static final String UNAME; 
    private static final String PWD; 

    static { 

     final ResourceBundle config = ResourceBundle 
       .getBundle("props.database"); 
     DRIVER_NAME = config.getString("driverName"); 
     URL = config.getString("url"); 
     UNAME = config.getString("uname"); 
     PWD = config.getString("pwd"); 

     dataSource = setupDataSource(); 
    } 

    public static Connection getOracleConnection() throws SQLException { 
     return dataSource.getConnection(); 
    } 

    private static DataSource setupDataSource() { 
     ComboPooledDataSource cpds = new ComboPooledDataSource(); 
     try { 
      cpds.setDriverClass(DRIVER_NAME); 
     } catch (PropertyVetoException e) { 
      e.printStackTrace(); 
     } 
     cpds.setJdbcUrl(URL); 
     cpds.setUser(UNAME); 
     cpds.setPassword(PWD); 
     cpds.setMinPoolSize(5); 
     cpds.setAcquireIncrement(5); 
     cpds.setMaxPoolSize(20); 
     return cpds; 
    } 
} 

в DAO я буду писать что-то вроде этого:

try { 
      conn = DBConnection.getOracleConnection(); 

      .... 


} finally { 
    try { 
     if (rs != null) { 
      rs.close(); 
     } 
     if (ps != null) { 
      ps.close(); 
     } 
     if (conn != null) { 
      conn.close(); 
     } 
    } catch (SQLException e) { 
     logger 
       .logError("Exception occured while closing cursors!", e); 

    } 

Теперь, мой вопрос я должен беспокоиться, чтобы делать какие-либо другие убирать, кроме закрытия курсоров (подключение/заявление/resultSet/prepareStatement), перечисленные в блоке finally.

Что такое this Очистка ?? Когда и где я должен это делать?

Если вы обнаружили что-то не так в приведенном выше коде, укажите, пожалуйста.

+0

в JDK 7 вам не нужно закрывать готовое приложение, оно реализует AutoClosable. [из-за этого сообщения] (http://stackoverflow.com/questions/14862853/resource-leak-warning-in-eclipse) –

ответ

20

С объединенным источником данных соединения в пуле фактически не закрыты, они просто возвращаются в пул. Однако, когда приложение закрыто, эти подключения к базе данных должны быть надлежащим образом и фактически закрыты, в которые входит окончательная очистка.

Кстати, проект c3p0 в значительной степени мертв в воде, я рекомендую вам используйте вместо этого Apache Commons DBCP, он все еще поддерживается.

+7

@ skaffman: Я собирался переключиться с DBCP на C3P0 после прочтения почти противоположного тому, что вы сказали здесь: http://stackoverflow.com/questions/520585/connection-pooling-options-with-jdbc-dbcp-vs-c3p0. Теперь я не уверен: похоже, что ни один проект не имел много TLC в последнее время. – Adamski

+0

@ Адамски: Я тебя слышу. Определенный разрыв на рынке. – skaffman

+2

Используйте BoneCP, очень активный, отличный инструмент, хорошая документация, очень быстро. Мы используем его на очень высоком участке трафика и не испытываем никаких проблем. – Janning

3

Код выглядит хорошо для меня, но я бы написал вспомогательный метод, который выполняет операции закрытия, или вы получите этот подробный окончательный блок в каждом DAO или методе. Возможно, вам нужно написать три отдельных блока try-catch вокруг тесных операций, чтобы убедиться, что соединение закрыто независимо от того, вызвал ли вывод и результат набор. Также обратите внимание, что javadoc says

Когда объект Statement закрыт, его текущий объект ResultSet, если он существует, также закрыт.

Так что вам не нужно закрывать набор результатов в приведенном выше примере, но вы могли бы.

Связанный метод очистки предназначен для закрытия источника данных, что не требуется в большинстве проектов, поскольку DS живет до тех пор, пока ваше приложение работает.

5

DAO не должны нести ответственность за подключение к базе данных. У них нет возможности узнать, когда они используются как часть более крупной транзакции. Вы должны передать источник данных или экземпляр соединения в DAO.

Если какой-либо из вызовов, которые нужно закрыть в вашем блоке finally, выдает исключение, ни один из следующих ниже не будет вызван. Каждый из них должен быть в своем собственном блоке try/catch. Я помещал их в класс утилиты как статические методы.

0

Я использую Play Framework и Scala, поэтому следующий пример показан в проекте игры.

Шаг1. configuration

В build.sbt, если вы используете базу данных mysql/hive as, вам необходимо добавить эти свойства.

libraryDependencies ++ = Seq (
    jdbc, 
    "mysql" % "mysql-connector-java" % "5.1.31", 
    "org.apache.hive" % "hive-jdbc" % "0.12.0", 
    "com.mchange" % "c3p0" % "0.9.2.1" 
) 

Шаг2. как получить к нему доступ? вам нужно импортировать библиотеку c3p0.

import com.mchange.v2.c3p0.ComboPooledDataSource 

Шаг 3. а затем вам нужно создать экземпляр.

val cpds = new ComboPooledDataSource() 
cpds.setDriverClass(...) 
cpds.setJdbcUrl(...) 
cpds.setUser(...) 
cpds.setPassword(...) 

Шаг4. вы получаете соединение

cpds.getConnection 
Смежные вопросы