使用singleton类、Tomcat、C3P0管理Java web应用程序中的池数据源
我有一个java web应用程序运行在黑板学习软件中,它使用Tomcat5.5。 该应用程序连接到外部数据库 我没有在Blackboard服务器上声明数据源的权限,所以我正在尝试打包web应用程序中的所有内容。尽管在使用后仔细关闭了所有结果集、语句和连接,但我的基于commons的池方法仍然存在连接不足的问题。 我现在切换到C3P0池方法,但我不确定我的一般方法是否正确 我使用一个单例类来创建数据源,目的是最小化实现连接池的数据源的创建和破坏。下面的课程应该清楚地说明这一点。这是一种合理的方法,还是可能导致我之前的连接不足问题 谢谢 编辑。更新问题,以澄清单件方法的目的。我试图避免每次需要db连接时创建数据源。这似乎抵消了连接池的好处 数据源类:使用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池方法,但我不确定我的一般方法是否正确 我使用一个单例类来创建数据源,目的是最小化实现连接池的数据源的创建和破坏。下面的课程应该清楚地说明这一点。这是一种合理的方法,
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的有用答案时指出的,最初的问题仍然没有得到回答。因此,我为其他也有兴趣找到问题答案的人提供了一些背景。我不想确认。如果你没有什么建设性的东西要补充,你来这里干什么?嗨,莱米,我会让我的代表在这一周的每一天与你的代表对抗。看看这个,乔普指出我的回答是中肯的。在我看来,你在寻求确认。