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的做法,但感觉上文全是废话。请看官多留言交流。