LoginSignup
7
3

More than 5 years have passed since last update.

SkinnyORMからOracleに接続するために変更した点

Posted at

SkinnyFrameworkにてScaffoldしたモデルからOracleに接続するために変更したところをメモ。

試した環境としては、

  • Windows 8.1
  • SkinnyFramework 1.3.4
  • Oracle 10g

ですが、他のOS等でも大丈夫だと思います。

1. JDBCドライバの依存設定

OracleのJDBCドライバはMavanRepositoryに登録されていないため、以下のいずれかの方法で参照を追加する必要があります。

  1. libディレクトリに置く
  2. ローカルのMavenリポジトリに発行して利用する

一番手軽なのは方法1で特に説明もいらないと思います。
ただし、方法1の場合だと実行可能JARファイルを出力(skinny package:standalone)した際にJDBCドライバが含まれないようですので、ここでは方法2を説明します。

1.1. JDBCドライバをローカルのMavenリポジトリに登録する

まずはJDBCドライバを用意して、ローカルのMavenリポジトリに登録します。mvnコマンドが必要となりますので、まだの方はここでインストールしましょう。手順は省略します。

JDBCドライバのファイル(ここでは ojdbc14.jar)を配置したディレクトリでコマンドプロンプトを開き、以下のコマンドを実行します。

rem 以下は1行で入力する
C:\jdbc> mvn install:install-file -Dfile=ojdbc14.jar -DgroupId=com.oracle -DartifactId=ojdbc -Dversion=14 -Dpackaging=jar

rem 改行したい場合は、行の末尾に ^ を付けます
C:\jdbc> mvn install:install-file -Dfile=ojdbc14.jar ^
                                  -DgroupId=com.oracle ^
                                  -DartifactId=ojdbc ^
                                  -Dversion=14 ^
                                  -Dpackaging=jar

それぞれのパラメータについてはMavenの説明などを参照してください。ここでは省略します。

1.2. JDBCドライバを参照するように ビルドファイル project/Build.scala を更新する

上の手順で登録したJDBCドライバを参照するように、ビルドファイルを更新します。

// project/Build.sbt を一部抜粋
// baseSettings を更新すればいいはず。

lazy val baseSettings = ScalatraPlugin.scalatraWithJRebel ++ herokuSettings ++ Seq(
  // ...

  libraryDependencies ++= Seq(
    // Oracle の JDBC ドライバを追加
    "com.oracle" % "ojdbc" % "14"
  ),
  resolvers ++= Seq(
    // ローカルの Maven リポジトリを追加
    Resolver.mavenLocal
  )

  // ...
)

更新後、OracleのJDBCドライバが利用できるようになります。

2. Oracleへのコネクション設定

DBへの接続設定は、設定ファイル src/main/resources/application.conf へ書きますが、デフォルトのまま利用すると以下のエラーが発生するはずです。

2014-11-03 15:24:29.091 ERROR   --- [p1111954787-431] controller.Controllers$search$           : Cannot get a connection, pool error Unable to validate object
java.sql.SQLException: Cannot get a connection, pool error Unable to validate object

エラーが発生する理由の一つとして、デフォルトで設定されているコネクション確認用のクエリがOracleに通らないというものがあります。

該当の接続設定のpoolValidationQueryを、以下のとおりDUAL表を参照するように変更します。

(変更前)
poolValidationQuery="select 1 as one"

(変更後)
poolValidationQuery="select 1 as one from dual"
                                    ^^^^^^^^^^

3. テーブルのカラム名が取得できない?

SkinnyORMからクエリを投げる際に、カラム名をMetaDataから取得しているようですが、自分の環境では取得できなかったため、以下のエラーが発生してました。

No column found for persons. If you use NamedDB, you must override connectionPoolName.

カラム名が取得できないため、暫定的に手動でカラム名を設定します。
(時間があったら解決方法を探します。)

// 以下のモデルがあるとして
case class Person(
  id: Long,
  name: String,
  birthDay: DateTime
)

object Person extends ... {

  // columnNames メソッドをオーバーライドして、snake_caseのカラム名を返すようにする。
  override def columnNames = Seq("id", "name", "birth_day")

}

4. ページネーションが効かない

公式サイトにもありますが、Oracle(とSQLServer)への接続にはページネーションをサポートしていません。

Scaffolding - Skinny Framework
http://skinny-framework.org/documentation/scaffolding.html#skinnyresource's-paginaation-for-oracle,-ms-sqlserver

上記ページに書いてあるとおり、SkinnyModel#findModels(pageSize: Int, pageNo: Int): List[Model]をカスタマイズすることでページネーションをすることが可能とあります。
DBにもメモリにもやさしくないですが、件数が少ない場合は全件取得してScalaのメソッドで対応すると楽です。
ちゃんとしたクエリを発行する方法については、調べてから更新しようと思います。

object Person extends ... {

  // 良くない実装ですが、すごく簡単。
  override def findModels(pageSize: Int, pageNo: Int): List[Person] = {
    val limit = pageSize
    val offset = pageSize * (pageNo - 1)
    findAll().drop(offset).take(limit)
  }

}

まとめ

とりあえず上記の対応をすることで、ScaffoldしたモデルからOracleに接続できるようになります。
それ以外にも必要なところがあれば随時更新していきます。

7
3
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3