Управление источником данных пула в веб-приложении Java с помощью одноэлементного класса, Tomcat, C3P0 - PullRequest
0 голосов
/ 16 февраля 2012

У меня есть веб-приложение на Java, работающее в обучающей программе Blackboard, которая использует Tomcat 5.5.Приложение подключается к внешней базе данных.

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

Я использую одноэлементный класс для создания источника данных с целью минимизации создания и уничтоженияИсточники данных, которые реализуют пул соединений.Следующие классы должны проиллюстрировать это ясно.Это разумный подход, или он, вероятно, способствовал моей предыдущей проблеме исчерпания соединений?

Спасибо.

РЕДАКТИРОВАТЬ.Обновленный вопрос для уточнения цели одноэлементного подхода.Я пытаюсь избежать создания источника данных каждый раз, когда мне нужно соединение с БД.Кажется, это сводит на нет преимущества наличия пула соединений.

Класс источника данных:

import java.beans.PropertyVetoException;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import com.mchange.v2.c3p0.*;

public class MyDataSource {

private static MyDataSource mds = new MyDataSource();
public static DataSource ds;

private MyDataSource() {
    try {
        ds = getDataSource();
    } catch (NamingException e) {
        e.printStackTrace();
    }
}

public static MyDataSource getInstance(){
    return mds;
}

public Connection getConnection() throws SQLException, NamingException {
    Connection myConnect = ds.getConnection();
    return myConnect;
}

private DataSource getDataSource() throws NamingException {

    ComboPooledDataSource cpds = new ComboPooledDataSource(); 
    try {
        cpds.setDriverClass( "com.mysql.jdbc.Driver" );
    } catch (PropertyVetoException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    cpds.setJdbcUrl( "jdbc:mysql://195.195.xx.xx:3306/dbName" ); 
    cpds.setUser("lemmy"); 
    cpds.setPassword("xxx");
    cpds.setMaxIdleTime(180);
    cpds.setMaxPoolSize(100);       
    return cpds;
}
 }

Класс соединения:

import java.sql.*;
import javax.sql.*;
import javax.naming.*;

public class DbConnection {

public Connection c;

public DbConnection() throws NamingException, SQLException {
    c = getConnection();
}

public Connection getConnection() throws SQLException, NamingException {        
    Connection myConnect = MyDataSource.getInstance().getConnection();
    return myConnect;       
}

public void close(){
    JDBCUtils.close(this.c);
}
}

Закрытие соединений и т. Д.

import java.sql.*;

public class JDBCUtils {

static public void close (ResultSet rs) {
    try { if (rs!=null) rs.close(); } catch (Exception e) {}
    }

  //  Works for PreparedStatement also since it extends Statement.
  static public void close (Statement stmt) {
    try { if (stmt!=null) stmt.close(); } catch (Exception e)   {}
    }

  static public void close (java.sql.Connection conn) {
    try { if (conn!=null) conn.close(); } catch (Exception e) {}
    }   

}

Пример использования:

    String myQuery = null;
    DbConnection myConnect = null;
    Statement myStatement = null;
    ResultSet rs = null;

    try {
       myConnect = new DbConnection();
        myStatement = myConnect.c.createStatement();

                // Do stuff here

        }catch (SQLException e) {
    out.println("SQL Error: "+e);
    } finally {
        JDBCUtils.close(rs);
        JDBCUtils.close(myStatement);
        myConnect.close();
    }

Ответы [ 2 ]

1 голос
/ 16 февраля 2012

Возможно, вы захотите взглянуть на JdbcTemplate из каркаса пружины.Вы можете использовать его автономно, поскольку у Spring есть требование предоставить множество вспомогательных классов.Это упрощает задачу вложенности соединения / оператора / набора результатов.Кроме того, он обрабатывает запросы проще.

Я знаю, что в учебных целях вы, вероятно, не будете использовать JdbcTemplate, но дизайн класса интересен.

Об объединении уже есть ответ @duffymo.

0 голосов
/ 16 февраля 2012

Я думаю, что это неправильная идея во всех отношениях.

Вам нужно несколько соединений в пуле соединений.Позвольте пулу управлять жизненным циклом;он будет амортизировать стоимость создания по каждому запросу.

Синглтон будет означать один запрос на каждый.Это не имеет смысла для меня.

Ваше приложение должно использовать соединения следующим образом: по одному на запрос.Получить его, использовать его, вернуть его в пул в рамках одного метода.Так будет лучше.Меньше кода для вас, чтобы написать.Настройте его как ресурс данных JNDI, и все готово.

...