独自のjarを使わねば、なのじゃあ。
Scalaを使っていると、時として、mavenなどのリポジトリにないjarを用いてちょっとしたコードを書かなければならない時がある。久々にそんな機会があったので、sbtではなくgradleを使ってみて独自のjarを導入してみた。最近、gradle使ってなかったし、Oracleにけっこうはまったので備忘録を。
※ gradle入門は例えばこのあたり
https://tech-lab.sios.jp/archives/9500
gradleにscalaを導入
はじめに、gradleをインストール。sdkmanの場合:
sdk install gradle
対象フォルダで:
gradle init --type scala-library
これにより、以下のようなフォルダ構成ができあがる。
(Oracle RDSに接続するコードのため、名前空間はord.rds)
$ tree .
.
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
├── main
│ ├── resources
│ └── scala
│ └── ora
│ └── rds
│ └── Library.scala
└── test
├── resources
└── scala
└── ora
└── rds
└── LibrarySuite.scala
build.gradleを書き換え、必要ライブラリを配置
トップ下にあるbuild.gradleを書き換える。書き換えポイントは以下、①~③
apply plugin: 'scala'
apply plugin: 'application' //①gradle runできるようにする
repositories {
jcenter()
}
dependencies {
// Use Scala 2.12 in our library project
implementation 'org.scala-lang:scala-library:2.12.8'
// Use Scalatest for testing our library
testImplementation 'junit:junit:4.12'
testImplementation 'org.scalatest:scalatest_2.12:3.0.5'
// Need scala-xml at test runtime
testRuntimeOnly 'org.scala-lang.modules:scala-xml_2.12:1.1.1'
compile fileTree(dir: 'lib', include: '*.jar') //② lib フォルダ直下のjarを全て取り込む指定
}
mainClassName = 'OracleConnectSample' //③実行したいクラス名
※gradleのアプリケーションプラグインについてはこのあたりを参考。
libフォルダを作り、必要なjarファイルを置く(ここではOracleが配布しているJDBC thinドライバー)
.
├── lib
│ └── ojdbc7.jar
ScalaでOracle RDS接続
ただJDBC使っているだけなんだけど、忘れつつあるので...結構前の先人のブログを参考に。
import java.sql.{DriverManager, Connection, Statement, ResultSet,SQLException}
object OracleConnectSample {
val jdbcURL = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=XXXX.ap-northeast-1.rds.amazonaws.com) (PORT=1521))(CONNECT_DATA=(SID=YYYY)))"
val user ="ユーザー名"
val passwd ="パスワード"
def main(args : Array[String]) : Unit = {
try {
Class.forName("oracle.jdbc.driver.OracleDriver") //.newInstance()
val con = DriverManager.getConnection(jdbcURL,user,passwd)
try {
val stmt = con.createStatement()
val str ="SELECT sysdate,TO_CHAR(SYSDATE,'DY') FROM dual" //現在時刻と曜日を取得するSQL
val rs = stmt.executeQuery(str)
while (rs.next()){
println(s"${rs.getString(1)} ${rs.getString(2)}")
}
stmt.close()
} catch {
case e : SQLException => println("Database error "+e)
case e : Throwable => {
println("Some other exception type:")
e.printStackTrace()
}
} finally {
con.close()
}
} catch {
case e : SQLException => println("Database error "+e)
case e : Throwable => {
println("Some other exception type:")
e.printStackTrace()
}
}
}
}
ポイントは、(普段Oracleに縁がない人の場合)Oracle RDS向けのJDBC接続の書き方かな。
jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=XXXX.ap-northeast-1.rds.amazonaws.com) (PORT=1521))(CONNECT_DATA=(SID=YYYY)))
あと、SQL文字列の最後にセミコロンを入れると、以下のエラーが出るようなので注意。
Database error java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended
実行結果
$ gradle run
> Task :run
2019-02-23 14:45:30.0 SAT
BUILD SUCCESSFUL in 1s
2 actionable tasks: 1 executed, 1 up-to-date
オーケー、データベースの時刻もJSTとして正しいようだ。