2

我正在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())
    }
  }
}

我不再收到异常,因为我通过使用 PreExecution tait 来抑制它。但我仍然想知道这里出了什么问题。

4

3 回答 3

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()
于 2012-05-15T09:07:35.067 回答
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 之前。我希望这会有所帮助。

于 2013-05-19T05:38:24.960 回答
0

驱动程序只加载一次。

没有合适的驱动程序通常意味着连接 URL 语法不正确。

于 2012-05-14T13:30:16.693 回答