JForum源代码研究—数据库连接池

JForum是如何实现多种数据库连接/连接池方法的?

建立数据库连接的简单方法示意如下:

Connection conn = DriverManager.getConnection(url);

JForum支持单连接和多种连接池实现,每种连接实现都要继承DBConnection。包括:C3P0PooledConnect、DataSourceConnection、SimpleConnection(PooledConnection空继承了C3P0PooledConnect)。

public abstract class DBConnection 
{
    ...
    public abstract void init() throws Exception;
    public abstract Connection getConnection();
    public abstract void releaseConnection(Connection conn);
    public abstract void realReleaseAllConnections() throws Exception;
    ...
}

init()方法仅在系统启动时调用一次。C3P0PooledConnect的init()方法用于:

  • 新建ComboPooledDataSource对象
  • 设置驱动器类
  • 设置URL
  • 设置最小、最大池大小
  • 等其他设置

DataSourceConnection的init()方法用于:初始化javax.sql.DataSource对象。

SimpleConnection的的init()方法用于:建立单个连接,并销毁该连接。其实,目的是检验能否建立连接。例如:初始安装JForum时,可用于检验数据库配置是否正确。不会用于DAO操作。

C3P0PooledConnect的getConnection()方法用于:ComboPooledDataSource.getConnection()。

DataSourceConnection的getConnection()方法用于:DataSource.getConnection()。

SimpleConnection的getConnection()方法用于:DriverManager.getConnection(url)。

对于releaseConnection(Connection),三个类的实现都一样:Connection.close()。

对于realReleaseAllConnections(),C3P0PooledConnect的实现是com.mchange.v2.c3p0.DataSources.destroy(this.ds)。其他两个类都是空实现。

新建数据库连接对象时,不具体声明某种具体的连接,如:C3P0PooledConnect conn = ...,而是使用DBConnection conn = DBConnection.createInstance()和getImplementation()。createInstance()通过Class.forName()新建一个配置的连接实现类。

...
private static DBConnection instance;	

public static boolean createInstance()
	{
		try {
			instance = (DBConnection)Class.forName(SystemGlobals.getValue(
					ConfigKeys.DATABASE_CONNECTION_IMPLEMENTATION)).newInstance();
		}
		catch (Exception e) {
			 logger.warn("Error creating the database connection implementation instance. " + e);
			 e.printStackTrace();
			 return false;
		}
		
		return true;
	}
 

如果我们在自己的项目中要实现多种数据库连接/连接池,可以借鉴JForum的做法。但是有一点,如果想要使用其它的连接池实现,如DBCP,JForum支持吗?应该是不支持的。除非我们自己新建一个类DBCPConnection,并继承DBConnection。

后记:试图想深学习一点JForum的做法,但感觉上文全是废话。请看官多留言交流。

相关推荐