読者です 読者をやめる 読者になる 読者になる

Scala-dbc による DB 操作 - select 文の実行

以前から、Scala には DB アクセス用の API が用意されているが(lib/scala-dbc.jar)、情報が少なくドキュメント等で使い方を紹介されているのを見たことが無い。
ということで、前から気になっていたので試しに使ってみた。

簡単に使ってみた限りでは、PostgreSQL 用の Vendor クラスしか用意されていない等、洗練されていない部分も多く、未完成の印象が強い。(dbc2 があるようで、見た感じはそちらの方が使い易そうな印象)
今のところ、使いこなすにはソースを参照するしか無さそうだが、暗黙の型変換(Implicit Conversions)等を理解していないと読み解くのが困難だと思う。

今回、使用した環境は以下の通り。

Select 文の実行

今回は以下のような MySQL 上のテーブルの全レコードを出力してみることにする。

  • customer テーブル
    • id フィールド: INT
    • name フィールド: VARCHAR(40)

スクリプトの内容は以下の通り。

  1. MySQL 用の Vendor を用意
    • Vendor を継承する場合 abstract 宣言されている uri, user, pass, urlProtocolString, nativeDriverClass, retainedConnections を定義
  2. Database のインスタンス
  3. select, fields, from を使って Select 文の構成を記述
    • "of データ型" で適切なデータ型を指定しないと IncompatibleSchema 例外が発生するので注意
  4. executeStatement で SQL 文を実行

なお、executeStatement 内でコネクションの close も実施しているようなので別途実施する必要は無さそう。

customer_select.scala
import scala.dbc._
//of で指定する型(integer や characterVarying)を使用できるようにする
import scala.dbc.syntax.DataTypeUtil._
//select 等の SQL 文を構成するメソッドや implicit conversions を
//実行できるようにする
import scala.dbc.syntax.Statement._
import java.net.URI

//MySQL用の Vendor クラス作成
case class MySQL(val uri: java.net.URI, user: String, pass: String) extends Vendor {
    val urlProtocolString = "jdbc:mysql:"
    val nativeDriverClass = Class.forName("com.mysql.jdbc.Driver")
    val retainedConnections = 5
}

val db = new Database(MySQL(new URI("jdbc:mysql://localhost/test"), "root", ""))
try {
    //select で SelectZygote
    //fields で SelectOf、
    //from で SelectBeyond 生成
    //fields の中では 文字列から SelectDerivedField を経て、
    //SelectDerivedColumns への変換が行われる
    val st = select fields {
                ("id" of integer) and ("name" of characterVarying(40))
            } from "customer"

    //statement.Select に変換されて実行
    val rows = db.executeStatement(st)

    rows foreach {r =>
        r.fields foreach {f =>
            print(f.content.sqlString + ", ")
        }
        println()
    }
}
catch {
    case e: Exception => e.printStackTrace
}
実行例
>scala customer_select.scala
1, '顧客A',
2, 'customer2',
3, 'テスト',

なお、実行にあたっては予め MySQLJDBC ドライバー(JAR ファイル)を CLASSPATH に設定する等しておく必要がある。