我正在scala中编写自己的数据库。为了验证我的结果是否正确,我在specs2规范中检查了MySQL。我得到了正确的结果,一切都很好。但如果我再次运行测试而没有任何更改,我会得到一个SQLException: No suitable driver found for jdbc:mysql://localhost:3306/DBNAME?user=DBUSER (null:-1)
。为什么驱动程序没有再次加载?
修改
import java.sql.{ Connection, DriverManager, ResultSet }
import org.specs2.mutable.Specification
// SDDB imports ...
class DBValidationSpec extends Specification {
"SDDB and MySQl" should {
// SDDB
// ...
// JDBC
val connectionString = "jdbc:mysql://localhost:3306/sddb_test?user=root"
val query = """SELECT content, SUM( duration ) duration
FROM test
WHERE times
BETWEEN '2011-12-08'
AND '2011-12-09'
GROUP BY content"""
classOf[com.mysql.jdbc.Driver]
"give the same result" in {
// ...
//sddbResult
lazy val conn = DriverManager.getConnection(connectionString)
try{
val rs = conn.createStatement().executeQuery(query)
var mysqlResult = Map[List[String], Int]()
while (rs.next) {
mysqlResult += (rs.getString("content") :: Nil) -> rs.getInt("duration")
}
sddbResult == mysqlResult && sddbResult.size == 478 must beTrue
} finally {
conn.close()
}
}
}
}
我遗漏了代码的某些部分,因为它们不属于这个问题。
编辑#2
问题变得更加怪异了。我添加了第二个测试用例。测试用例使用相同的connectionString
。异常只提出一次。第二次测试成功了。我将sequential
添加到我的测试定义中,发现只有第一个执行的测试才会引发异常。然后我跟踪classLoader
以检查它是否是同一个。它是。
我做了以下解决方法:
trait PreExecuting extends Before {
override def before {
var conn: Option[Connection] = None
try {
val connectionString = "jdbc:mysql://localhost:3306/sddb_test?user=root"
conn = Some(DriverManager.getConnection(connectionString))
} catch {
case _ =>
} finally {
conn map (_.close())
}
}
}
我不再得到Exception了,因为我使用PreExecution tait来抑制它。但我仍然想知道这里出了什么问题。
答案 0 :(得分:1)
我无法将错误归结为以下内容,但至少还要关闭结果集和声明。
val stmt = conn.createStatement()
val rs = stmt.executeQuery(query)
var mysqlResult = Map[List[String], Int]()
while (rs.next) {
mysqlResult += (rs.getString("content") :: Nil) -> rs.getInt("duration")
}
sddbResult == mysqlResult && sddbResult.size == 478 must beTrue
rs.close()
stmt.close()
答案 1 :(得分:1)
这似乎是驱动程序注册的问题,驱动程序必须像这样注册...
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
or some like this...
DriverManager.registerDriver(new DriverWrapper((Driver) Class.forName(props.getProperty("dbg.driver"), true, gcloader).newInstance()));
使用getConnection之前。我希望这有帮助。
答案 2 :(得分:0)
驱动程序只加载一次。
没有合适的驱动程序通常意味着连接URL语法不正确。