S-JIS[2011-01-16] 変更履歴
ScalaのdbcのDatabaseおよびVendorクラスのメモ。
DBMSには色々な種類がある為、接続URIに応じてJDBCドライバーを切り替える必要がある。
そのため、Databaseオブジェクトのdatabase()メソッドを使ってDBを取得する。
import scala.dbc.syntax.Database
val db = Database.database("jdbc:oracle:thin:@localhost:1521:ora92", "scott", "tiger") val rows = db.executeStatement(st)
しかしながら、Scala2.8ではPostgreSQLしかサポートされていない為、その他のDBMSでは実行できない。
Exception in thread "main" java.lang.Exception: No DBMS vendor support could be found for the given URI at scala.dbc.syntax.Database$.database(Database.scala:29)
そこで、database()メソッドの中で使われているVendorを自分で作成する。
Vendorクラスは、DBMSの情報(JDBCドライバーやURI)を保持するクラス。
import scala.dbc.Vendor import java.net.URI
DBMS | ソース | 備考 |
---|---|---|
PostgreSQL |
package scala.dbc.vendor; import compat.Platform abstract class PostgreSQL extends Vendor { def uri:java.net.URI; def user:String; def pass:String; val retainedConnections = 5; val nativeDriverClass = Platform.getClassForName("org.postgresql.Driver"); val urlProtocolString = "jdbc:postgresql:" } val vendor = new PostgreSQL { |
Scala2.8で唯一用意されているPostgreSQL用のVendorクラス。 |
Oracle |
case class Oracle(val uri: URI, val user: String, val pass: String) extends Vendor { def retainedConnections = 1 def nativeDriverClass = Class.forName("oracle.jdbc.driver.OracleDriver") def urlProtocolString = "jdbc:oracle:" } val vendor = new Oracle( |
uri・user・passはVendor内で定義されている抽象メンバーのオーバーライドなので、変数名を変えてはいけない。 |
def nativeDriverClass = classOf[oracle.jdbc.driver.OracleDriver] |
OracleDriverがコンパイル時のクラスパスに入っていれば、左記のように記述可能。 | |
JavaDB |
case class JavaDB(val uri: URI, val user: String, val pass: String) extends Vendor { def retainedConnections = 1 def nativeDriverClass = Class.forName("org.apache.derby.jdbc.AutoloadedDriver") def urlProtocolString = "jdbc:derby:" private lazy val properties = super.nativeProperties def put(key: String, value: String) = properties.put(key, value) override def nativeProperties = properties } val vendor = new JavaDB(new URI("jdbc:derby:C:/temp/javadb/sample1"), "", "") |
接続時に使用されるプロパティーはnativePropertiesというメソッドで取得できるが、 デフォルトでは毎回インスタンスを作り直すので、値を設定したい場合は自分で保持しておく必要がある。 |
Vendorを使ったDatabaseクラスのインスタンス生成は以下のように行う。
import scala.dbc.Database import java.net.URI
val vendor = new Oracle(new URI("jdbc:oracle:thin:@localhost:1521:ora92
"), "scott", "tiger")
val db = new Database(vendor)
try {
〜
} finally {
db.close
}
※ここで出てくる「Database」は「scala.dbc.Databaseクラス」であって、「scala.dbc.syntax.Databaseオブジェクト」ではない。