Пул соединений JDBC с использованием C3P0 - PullRequest
29 голосов
/ 22 сентября 2009

Вот мой вспомогательный класс для подключения к БД:

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

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

    }

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

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

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

Ответы [ 4 ]

23 голосов
/ 22 сентября 2009

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

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

6 голосов
/ 22 сентября 2009

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

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

5 голосов
/ 22 сентября 2009

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

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

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

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

0 голосов
/ 24 ноября 2014

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

Шаг1. конфигурация

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

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

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

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

Step4. Вы получаете соединение

cpds.getConnection
...