因?yàn)樗械腎DatabaseTester實(shí)現(xiàn)(包括DefaultDatabaseTester)都繼承自AbatractDatabaseTester,這個(gè)抽象類有一個(gè)統(tǒng)一的執(zhí)行數(shù)據(jù)庫(kù)操作的方法executeOperation,原代碼如下:
private void executeOperation(DatabaseOperation operation) throws Exception
{
logger.debug("executeOperation(operation={})- start", operation);
if(operation != DatabaseOperation.NONE ){
// IDatabaseTester 的 getConnection 方法,不是重載的那個(gè)。
IDatabaseConnection connection = getConnection();
try{
operation.execute(connection, getDataSet() );
}
finally{
closeConnection(connection);
}
}
}
我們看到每執(zhí)行完一次操作,數(shù)據(jù)庫(kù)連接都會(huì)被關(guān)閉,所以如果繼承DefaultDatabaseTester,將導(dǎo)致只能執(zhí)行一次數(shù)據(jù)庫(kù)操作。
如果希望在一個(gè)TestCase里執(zhí)行兩次操作,我們可以使用另一個(gè)基類
DBTestCase類
如上面所看到的,問(wèn)題出在DatabaseTestCase的newDatabaseTester方法返回了一個(gè)無(wú)法重復(fù)利用的DefaultDatabaseTester實(shí)例,所以DBTestCase的newDatabaseTester方法代碼變更如下:
protected IDatabaseTester newDatabaseTester() throws Exception {
return new PropertiesBasedJdbcDatabaseTester();
}
它用來(lái)生成實(shí)例的是 PropertiesBasedJdbcDatabaseTester 類,而不是 DefaultDatabaseTester 。這個(gè)類的父類 JdbcDatabaseTester(也繼承自 AbstractDatabaseTester)的 getConnection 方法:
public IDatabaseConnection getConnection() throws Exception
{
logger.debug("getConnection() - start");
if(!initialized ){
// 注意這個(gè)方法,等一下詳解
initialize();
}
assertNotNullNorEmpty("connectionUrl", connectionUrl);
Connection conn = null;
if(username == null && password == null ){
conn = DriverManager.getConnection(connectionUrl);
}else{
Conn = DriverManager.getConnection(connectionUrl,username,password);
}
return new DatabaseConnection( conn, getSchema() );
}
可以看到每次調(diào)用這個(gè)方法,都會(huì)新建一個(gè)連接,而不是簡(jiǎn)單的返回我們重載的 getConnection 中返回的連接的引用。這樣避免了 DefaultDatabaseTester 僅僅是簡(jiǎn)單返回之前的連接而倒置的問(wèn)題。不過(guò)這也意味著用 DBTestCase 不用我們自己去重載 getConnection 了,因?yàn)?DBTestCase 已經(jīng)實(shí)現(xiàn)了這個(gè)方法(DatabaseTestCase沒(méi)有實(shí)現(xiàn)):
protected IDatabaseConnection getConnection() throws Exception {
logger.debug("getConnection() - start");
final IDatabaseTester databaseTester = getDatabaseTester();
assertNotNull( "DatabaseTester is not set",databaseTester);
return databaseTester.getConnection();
}
我們看到DBTestCase的getConnection簡(jiǎn)單的把這個(gè)方法轉(zhuǎn)給JdbcDatabaseTester(IDatabaseTester) 的getConnection。而JdbcDatabaseTester的實(shí)現(xiàn)我們?cè)谇懊嬉呀?jīng)看到了。