我在Java中实现了一个非常简单的ConnectionPool。 它没有花哨的功能,只是获取/释放连接方法。
我如何测试它是否有效?
我知道有很多连接池可以在那里使用,它比我要做的更可靠,但我只是想练习理解连接池的工作方式。
谢谢!
以下是代码,以防它有用:
public class ConnectionPoolImpl implements ConnectionPool {
private Vector<PooledConnection> connections; // The connections container
String url;
String username;
String password;
/**
* Instanciates a new MySQLConnectionPool
* @param nbConnectionsMax
*/
public ConnectionPoolImpl(String DBUrl, String username, String password){
this.connections = new Vector<PooledConnection>();
this.url = DBUrl;
this.username = username;
this.password = password;
}
/**
* Returns a connection from the pool, if some are available, or create a new one.
*
* @return the connection.
*/
public Connection getConnection() throws SQLException {
synchronized(this.connections){
// Checking if there is an available connection to return
for(PooledConnection c : this.connections){
if(!c.isUsed()){
c.setUsed();
return c.getConnection();
}
}
// If there are none, open a new one and return it
Connection conn = DriverManager.getConnection(url, username, password);
PooledConnection pConn = new PooledConnection(conn);
pConn.setUsed();
connections.add(pConn);
return pConn.getConnection();
}
}
/**
* Releases a connection to the pool.
*
* @param con the connection to release.
*/
public void releaseConnection(Connection con) throws SQLException {
synchronized(this.connections){
for(PooledConnection c : this.connections){
if(c.getConnection().equals(con)){
c.setFree();
return;
}
}
}
}
}
我的PooledConnection.java:
public class PooledConnection {
private Connection conn;
private boolean used;
public PooledConnection(Connection conn){
this.conn = conn;
this.used = false;
}
public void setUsed(){
this.used = true;
}
public void setFree(){
this.used = false;
}
public boolean isUsed(){
return this.used;
}
public Connection getConnection(){
return this.conn;
}
}
答案 0 :(得分:12)
您可以测试
请注意,这样的单元测试需要一个真实的数据库,并且需要测试真实的用户和密码。您可以使连接池依赖于DataSource,并使用模拟DataSource返回模拟Connections来构建ConnectionPool,以便能够在不依赖真实数据库的情况下测试该类。
答案 1 :(得分:3)
对于集成测试,您可以使用dbUnit使用准备好的数据加载数据库,然后编写查询数据库的测试。
对于单元测试,您可以考虑使用模拟库(例如Mockito)来确保获得预期的行为。在这种情况下无需数据库。 [编辑:但是,由于静态方法调用如DriverManager.getConnection(),这将需要一些重构和/或依赖注入。]
通过结合单元测试和集成测试(并在一些多线程单元测试中混合使用),您可以大大地测试您的工作。
答案 2 :(得分:1)
工业强度连接池能够通过建立连接和执行简单的SQL查询(例如“SELECT 1”)来检查连接,以确保连接在发布之前是可行的。你的没有。
我看不到用固定数量的连接初始化连接池的位置。连接池的重点是分摊在所有客户端上创建连接的成本。
我担心你的连接池的设计。
至于测试,只需开始编写单元测试。由于您的池将被共享,请务必编写一些多线程测试以确保它真的是线程安全的。
答案 3 :(得分:0)
您还应该使用多个线程在负载下测试并发/可伸缩性。