使用singleton类、Tomcat、C3P0管理Java web应用程序中的池数据源

使用singleton类、Tomcat、C3P0管理Java web应用程序中的池数据源,java,singleton,datasource,connection-pooling,c3p0,Java,Singleton,Datasource,Connection Pooling,C3p0,我有一个java web应用程序运行在黑板学习软件中,它使用Tomcat5.5。 该应用程序连接到外部数据库 我没有在Blackboard服务器上声明数据源的权限,所以我正在尝试打包web应用程序中的所有内容。尽管在使用后仔细关闭了所有结果集、语句和连接,但我的基于commons的池方法仍然存在连接不足的问题。 我现在切换到C3P0池方法,但我不确定我的一般方法是否正确 我使用一个单例类来创建数据源,目的是最小化实现连接池的数据源的创建和破坏。下面的课程应该清楚地说明这一点。这是一种合理的方法,

我有一个java web应用程序运行在黑板学习软件中,它使用Tomcat5.5。 该应用程序连接到外部数据库

我没有在Blackboard服务器上声明数据源的权限,所以我正在尝试打包web应用程序中的所有内容。尽管在使用后仔细关闭了所有结果集、语句和连接,但我的基于commons的池方法仍然存在连接不足的问题。 我现在切换到C3P0池方法,但我不确定我的一般方法是否正确

我使用一个单例类来创建数据源,目的是最小化实现连接池的数据源的创建和破坏。下面的课程应该清楚地说明这一点。这是一种合理的方法,还是可能导致我之前的连接不足问题

谢谢

编辑。更新问题,以澄清单件方法的目的。我试图避免每次需要db连接时创建数据源。这似乎抵消了连接池的好处

数据源类:

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

我认为这在各方面都是错误的想法

您希望在一个连接池中有多个连接。让池管理生命周期;它将在每个请求上分摊创建成本

单身意味着每个人都有一个要求。那对我来说毫无意义

你的应用程序应该这样使用连接:每个请求一个。获取它,使用它,然后将它返回到单个方法范围内的池中。那样会扩展得更好。也可以编写更少的代码。将它设置为JNDI数据资源,您就可以开始了。

您可能希望从spring框架中查看。您可以单独使用它,因为Spring声称提供了许多帮助器类。这简化了连接/语句/结果集嵌套问题。此外,它还处理更简单的查询

我知道出于学习目的,您可能不会使用JdbcTemplate,但是类设计很有趣


关于池,@duffymo已经给出了答案。

单例意味着一个数据源。但是数据源提供了多个连接。或者我错了吗?这个想法是为了防止每次需要db连接时都实例化一个新的数据源,并确保一个数据源与其连接池一起使用。你在这里重新发明了一个轮子。我同意Joop Eggen的观点:Spring的SimpleJdbcTemplate比您以前做得更好。我不会写我自己的。谢谢。我会看看的。不过,我仍然不清楚我是否在现有方法的错误轨道上。我能找到的所有示例都使用web服务器上的数据源集。我发现了这个示例,它与静态数据源的方法类似:如果你只是想确认一下,你来这里干什么?@duffymo:正如我在回答Joop的有用答案时指出的,最初的问题仍然没有得到回答。因此,我为其他也有兴趣找到问题答案的人提供了一些背景。我不想确认。如果你没有什么建设性的东西要补充,你来这里干什么?嗨,莱米,我会让我的代表在这一周的每一天与你的代表对抗。看看这个,乔普指出我的回答是中肯的。在我看来,你在寻求确认。