Scalaからリレーショナル・データベースに接続する方法としては、
Java JDBCドライバを直接操作する方法と、scala.dbc かscala.dbc2を使う方法があります。
前者はJavaで書いていたと同じに使うことができます。
後者はまだ開発途上のようです。
現在、Javaでデータベースを操作する場合、JavaJDBCドライバのライブラリを直接使うよりはいろいろなフレームワークを利用しています。
我々も、現在 seedo.database パッケージを開発中です。
このパッケージの開発方針は、
1.ScalaのDBパッケージとしてリレーショナルデータベースを抽象化して、OracleやMySQL、DB2、SQL-Serverといった各種ベンダーの固有の機能や特徴を隠蔽しないことです。
ビジネスで使う限りはそのベンダーのデータベースの機能を使い切りたい。かといって型定義やSQL文法の細かい違いはできる限り吸収してしまいたい。
2.Scala文法とSQL文法を融合しない。インピーダンス・ミスマッチという古くて新しい言語問題です。
データベースを操作するために新しいライブラリや文法はもう覚えたくない。SQLはSQL言語として使うほうがいいと考えています。
3.プログラムのメンテナンス性を向上させる。読みやすさ重視です。ソースコードから動作がトレースできること。設計書やXMLなど設定ファイルを参照しなくてもプログラムの動作が追えることです。それと、JDBCは決まり文句が多すぎでした。Scalaのようにバッサリと無駄な記述はなくしてしまいたい。
4.性能は、Java JDBCドライバの関数で書いたものと遜色ないこと。
5.プログラム検証は、静的チェックが基本。プログラミングするよりプログラムテストの方がはるかにコストがかかりますから。動的チェックとしてSQL文の生成をデータベースのディクショナリを参照して実行する機能も有用でしょう。
今後の予定
2010年中にVersion1.0をリリースする予定でいます。
Javaとは違うScalaの良い特徴をいかした仕様になるよう研究中です。
scala.dbc2のいいところも取り入れましょう。Scalaらしい仕様だと思いますから。
SeeDo Scala Framework リリース
2011/1/1 になってしまいましたが、SeeDo Scala framework ( eWave Solutions Inc.(c) 2000-2011, LAMP/EPFL) をリリースします。
バージョンはVersion0.9 です。
downloadは、seedo.jar
JPAのannotationを使いますので、jpa.jarも download してください。
この2つのJarファイルを eclipse のプロジェットプロパティの Java ビルドパスの外部 JAR に追加します。
Oracleのsample user のscott のbean class のソースコードは、scott.zipから download できます。
DB アクセスは、テストコードで動作を確認できます。
Oracle11g でしか動作テストしていません。近日、MySQLで動作確認したバージョンをリリースします。
/* * SeeDo * eWave Solutions Inc.(c) 2000-2011, LAMP/EPFL */ package test import org.scalatest.junit.JUnitSuite import org.scalatest.junit.ShouldMatchersForJUnit import org.junit.Test import org.junit.Before import org.junit.After import org.junit.BeforeClass import org.junit.AfterClass import seedo._ import seedo.database._ import scott.bean._ class testDB extends JUnitSuite with ShouldMatchersForJUnit{ var drivrName = "oracle.jdbc.driver.OracleDriver" var jdbcURL = "jdbc:oracle:thin:@127.0.0.1:1521:ORCL" // var jdbcURL = "jdbc:oracle:thin:@192.168.0.105:1521:ORCL" var user ="scott" var passwd ="tiger" var db:Db = _ @Before def initialize() { println("Start") db = new Db(drivrName,jdbcURL,user,passwd) } @Test def verifyTable() { // Uses JUnit-style assertions & Uses ScalaTest assertions db.select("ENAME,HIREDATE,EMPNO").from("EMP").where("empno >= ?",7700).orderBy("ename") println(db.toString) println(db.getSql) println(" --- Array") db.executeQuery.foreach(c =>{ c.foreach(d => { print(" " + d) }) println }) println(" --- ColumnNameList") db.getColumnNameList.foreach(c =>{ print(" " + c) }) println db.select("*").from("EMP").where("empno >= ?",7700).orderBy("ename") println(" --- BEAN") println(db.toString) println(db.getSql) db.executeQuery[EMP](classOf[EMP]).foreach(c =>{ println(" " + c.toString + " " + c.toXml) println(" " + c.toJson + " " + c.toXmlModified) }) println(" --- ColumnNameList") db.getColumnNameList.foreach(c =>{ print(" " + c) }) println println(" --- DEPT table") db.select("*").from("DEPT").orderBy("deptno") db.executeQuery[DEPT](classOf[DEPT]).foreach(c =>{ println(" " + c.toString) }) println println(" --- Update") var empno = 7900 db.update("EMP").set("DEPTNO=?", 40).where("EMPNO=?",empno) println(" --- Update execute SQL="+db.toString) val rt = db.execute println(" --- before result="+rt.getResultSize) db.select("*").from("EMP").where("empno = ?",empno) db.executeQuery[EMP](classOf[EMP]).foreach(c =>{ println(" " + c.toString) }) println(" --- Rollback") db.rollback println(" --- after") db.select("*").from("EMP").where("empno = ?",empno) db.executeQuery[EMP](classOf[EMP]).foreach(c =>{ println(" " + c.toString) }) println println(" --- Begin transaction") db.begin println(" --- Insert") db.insertInto("EMP").column("empno,ename,hiredate,deptno,sal").values("?,?,sysdate,?,?", 1000,"曙",20,2001) println(" --- Insert execute SQL="+db.toString) val rt1 = db.execute println(" --- Insert result="+rt1.getResultSize) db.select("*").from("EMP").where("empno = ?",1000) db.executeQuery[EMP](classOf[EMP]).foreach(c =>{ println(" " + c.toString) }) println(" --- End Sql") println(" --- Delete") db.deleteFrom("EMP").where("empno=?",1000) println(" --- Delete execute SQL="+db.toString) val rt2 = db.execute println(" --- Delete result="+rt2.getResultSize) db.select("*").from("EMP").where("empno = ?",1000) db.executeQuery[EMP](classOf[EMP]).foreach(c =>{ println(" " + c.toString) }) println(" --- End Sql") println(" --- Commit") db.commit println(" --- Emp table list") db.select("*").from("EMP").orderBy("empno") db.executeQuery[EMP](classOf[EMP]).foreach(c =>{ println(" " + c.toString) }) println(" --- End Sql") } @After def close() { if(db != null) db.close println("End") } }
実行結果です。
Start JDBC Driver:Oracle JDBC driver Version:11.1.0.6.0-Production Database:Oracle Version:11.1 select ENAME,HIREDATE,EMPNO from EMP where empno >= ? order by ename [7700] select ENAME,HIREDATE,EMPNO from EMP where empno >= ? order by ename --- Array ADAMS 1987-05-23 00:00:00.0 7876 CLARK 1981-06-09 00:00:00.0 7782 FORD 1981-12-03 00:00:00.0 7902 JAMES 1981-12-03 00:00:00.0 7900 KING 1981-11-17 00:00:00.0 7839 MILLER 1982-01-23 00:00:00.0 7934 SCOTT 1987-04-19 00:00:00.0 7788 TURNER 1981-09-08 00:00:00.0 7844 --- ColumnNameList ENAME HIREDATE EMPNO --- BEAN select * from EMP where empno >= ? order by ename [7700] select * from EMP where empno >= ? order by ename 7876,ADAMS,CLERK,7788,1987-05-23 00:00:00.0,1100,null,20{"EMP" : {"EMPNO" : "7876","ENAME" : "ADAMS","JOB" : "CLERK","MGR" : "7788","HIREDATE" : "1987-05-23 00:00:00.0","SAL" : "1100","COMM" : "null","DEPTNO" : "20"}} 7876 ADAMS CLERK 7788 1987-05-23 00:00:00.000 1100 20 7782,CLARK,MANAGER,7839,1981-06-09 00:00:00.0,2450,null,10 7876 ADAMS CLERK 7788 1987-05-23 00:00:00.000 1100 20 {"EMP" : {"EMPNO" : "7782","ENAME" : "CLARK","JOB" : "MANAGER","MGR" : "7839","HIREDATE" : "1981-06-09 00:00:00.0","SAL" : "2450","COMM" : "null","DEPTNO" : "10"}} 7782 CLARK MANAGER 7839 1981-06-09 00:00:00.000 2450 10 7902,FORD,ANALYST,7566,1981-12-03 00:00:00.0,3000,null,20 7782 CLARK MANAGER 7839 1981-06-09 00:00:00.000 2450 10 {"EMP" : {"EMPNO" : "7902","ENAME" : "FORD","JOB" : "ANALYST","MGR" : "7566","HIREDATE" : "1981-12-03 00:00:00.0","SAL" : "3000","COMM" : "null","DEPTNO" : "20"}} 7902 FORD ANALYST 7566 1981-12-03 00:00:00.000 3000 20 7900,JAMES,CLERK,7698,1981-12-03 00:00:00.0,950,null,30 7902 FORD ANALYST 7566 1981-12-03 00:00:00.000 3000 20 {"EMP" : {"EMPNO" : "7900","ENAME" : "JAMES","JOB" : "CLERK","MGR" : "7698","HIREDATE" : "1981-12-03 00:00:00.0","SAL" : "950","COMM" : "null","DEPTNO" : "30"}} 7900 JAMES CLERK 7698 1981-12-03 00:00:00.000 950 30 7839,KING,PRESIDENT,null,1981-11-17 00:00:00.0,5000,null,10 7900 JAMES CLERK 7698 1981-12-03 00:00:00.000 950 30 {"EMP" : {"EMPNO" : "7839","ENAME" : "KING","JOB" : "PRESIDENT","MGR" : "null","HIREDATE" : "1981-11-17 00:00:00.0","SAL" : "5000","COMM" : "null","DEPTNO" : "10"}} 7839 KING PRESIDENT 1981-11-17 00:00:00.000 5000 10 7934,MILLER,CLERK,7782,1982-01-23 00:00:00.0,1300,null,10 7839 KING PRESIDENT 1981-11-17 00:00:00.000 5000 10 {"EMP" : {"EMPNO" : "7934","ENAME" : "MILLER","JOB" : "CLERK","MGR" : "7782","HIREDATE" : "1982-01-23 00:00:00.0","SAL" : "1300","COMM" : "null","DEPTNO" : "10"}} 7934 MILLER CLERK 7782 1982-01-23 00:00:00.000 1300 10 7788,SCOTT,ANALYST,7566,1987-04-19 00:00:00.0,3000,null,20 7934 MILLER CLERK 7782 1982-01-23 00:00:00.000 1300 10 {"EMP" : {"EMPNO" : "7788","ENAME" : "SCOTT","JOB" : "ANALYST","MGR" : "7566","HIREDATE" : "1987-04-19 00:00:00.0","SAL" : "3000","COMM" : "null","DEPTNO" : "20"}} 7788 SCOTT ANALYST 7566 1987-04-19 00:00:00.000 3000 20 7844,TURNER,SALESMAN,7698,1981-09-08 00:00:00.0,1500,0,30 7788 SCOTT ANALYST 7566 1987-04-19 00:00:00.000 3000 20 {"EMP" : {"EMPNO" : "7844","ENAME" : "TURNER","JOB" : "SALESMAN","MGR" : "7698","HIREDATE" : "1981-09-08 00:00:00.0","SAL" : "1500","COMM" : "0","DEPTNO" : "30"}} 7844 TURNER SALESMAN 7698 1981-09-08 00:00:00.000 1500 0 30 --- ColumnNameList EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO --- DEPT table 10,ACCOUNTING,NEW YORK 20,RESEARCH,DALLAS 30,SALES,CHICAGO 40,OPERATIONS,BOSTON --- Update --- Update execute SQL=update EMP set DEPTNO=? where EMPNO=? [40] [7900] --- before result=1 7900,JAMES,CLERK,7698,1981-12-03 00:00:00.0,950,null,40 --- Rollback --- after 7900,JAMES,CLERK,7698,1981-12-03 00:00:00.0,950,null,30 --- Begin transaction --- Insert --- Insert execute SQL=insert into EMP (empno,ename,hiredate,deptno,sal) values (?,?,sysdate,?,?) [1000] [曙] [20] [2001] --- Insert result=1 1000,曙,null,null,2011-01-01 14:27:28.0,2001,null,20 --- End Sql --- Delete --- Delete execute SQL=delete from EMP where empno=? [1000] --- Delete result=1 --- End Sql --- Commit --- Emp table list 7369,SMITH,CLERK,7902,1980-12-17 00:00:00.0,800,null,20 7499,ALLEN,SALESMAN,7698,1981-02-20 00:00:00.0,1600,300,30 7521,WARD,SALESMAN,7698,1981-02-22 00:00:00.0,1250,500,30 7566,JONES,MANAGER,7839,1981-04-02 00:00:00.0,2975,null,20 7654,MARTIN,SALESMAN,7698,1981-09-28 00:00:00.0,1250,1400,30 7698,BLAKE,MANAGER,7839,1981-05-01 00:00:00.0,2850,null,30 7782,CLARK,MANAGER,7839,1981-06-09 00:00:00.0,2450,null,10 7788,SCOTT,ANALYST,7566,1987-04-19 00:00:00.0,3000,null,20 7839,KING,PRESIDENT,null,1981-11-17 00:00:00.0,5000,null,10 7844,TURNER,SALESMAN,7698,1981-09-08 00:00:00.0,1500,0,30 7876,ADAMS,CLERK,7788,1987-05-23 00:00:00.0,1100,null,20 7900,JAMES,CLERK,7698,1981-12-03 00:00:00.0,950,null,30 7902,FORD,ANALYST,7566,1981-12-03 00:00:00.0,3000,null,20 7934,MILLER,CLERK,7782,1982-01-23 00:00:00.0,1300,null,10 --- End Sql End 7844 TURNER SALESMAN 7698 1981-09-08 00:00:00.000 1500 0 30
コメントを残す
コメントを投稿するにはログインしてください。