Scalaプログラム入門の4章の「関数の楽しみ。JDBCコネクションを閉じる必要がありません」のような、Scalaらしい操作でEmp表をSelectしてみました。
まず、C#のUsingをScalaで定義するためにControlオブジェクトと定義します。
関数を引き数として渡し、tryの中でパラメータ付きで呼び出します。処理が終わるとfinally で引数へcloseメソッドを呼び出します。
using関数を使えばcloseはこのなかで行われます。
object Control { def using[A <: {def close():Unit},B](param:A)(f:A => B):B= try { f(param) }finally { param.close() } }
次に、Emp表をSelectするEmpオブジェクトを作ります。
object Emp { import Control._ import java.sql.{DriverManager, Connection, Statement, ResultSet,SQLException} var jdbcURL = "jdbc:oracle:thin:@192.168.0.105:1521:ORCL" var user ="scott" var passwd ="tiger" def main(args : Array[String]) : Unit = { Class.forName("oracle.jdbc.driver.OracleDriver").newInstance() try { var list = using(DriverManager.getConnection(jdbcURL,user,passwd)) { conn => findEmp(conn) } } catch { case e:SQLException => println("Database error "+e) case e => { println("Some other exception type:") e.printStackTrace() } } } def findEmp(conn:Connection): Unit = using (conn.createStatement){st => using (st.executeQuery("SELECT * FROM EMP")){rs => while (rs.next()){ print(rs.getString("empno") + " ") print(rs.getString("ename") + " ") print(rs.getString("job") + " ") print(rs.getString("mgr") + " ") print(rs.getString("hiredate") + " ") print(rs.getString("deptno") + " ") println(rs.getString("sal")) } } } }
実行結果は、JDBCコネクションで書いたScalaと同じです。
Scala入門第4章のように書く
先のプログラムをScala入門第4章のように書くと、まず、Emp表の値を格納するEmployeeクラスを定義します。
import java.util.Date class Employee (var empno:Int ,var ename:String ,var job:String ,var mgr:Int ,var hiredate:Date ,var deptno:Int ,var varsal:Int) { def getEmpno = empno def getEname = ename def getJob = job def getMgr = mgr def getHiredate = hiredate def getDeptno = deptno def getVarsal = varsal def setEmpno(value:Int):Unit = empno = value def setName(value:String) = ename = value def setDeptno(value:Int) = deptno = value override def toString() = "[Employee empno:"+empno+",ename:"+ename+",job:"+job+",mgr:"+mgr+",hiredate:"+hiredate+",deptno:"+deptno+",varsal:"+varsal+"]" }
先ほど作ったControlオブジェクトにbmapを追加します。
object Control { def using[A <: {def close():Unit},B](param:A)(f:A => B):B= try { f(param) }finally { param.close() } import scala.collection.mutable.ListBuffer def bmap[T] (test: => Boolean)(block: => T):List[T] = { val ret = new ListBuffer[T] while(test) ret += block ret.toList } }
Bmapを使ってSelectした結果のレコードをListに追加し、foreachで結果を表示します。
object Emp { import Control._ import java.sql.{DriverManager, Connection, Statement, ResultSet,SQLException} var jdbcURL = "jdbc:oracle:thin:@192.168.0.105:1521:ORCL" var user ="scott" var passwd ="tiger" def main(args : Array[String]) : Unit = { Class.forName("oracle.jdbc.driver.OracleDriver").newInstance() var conn:Connection = null try { conn = DriverManager.getConnection(jdbcURL,user,passwd) var list = findEmp(conn) list.foreach(l => println(l)) } catch { case e:SQLException => println("Database error "+e) case e => { println("Some other exception type:") e.printStackTrace() } } finally { conn.close() } } // def findEmp(conn:Connection): Unit = def findEmp(conn:Connection): List[Employee] = using (conn.createStatement){st => using (st.executeQuery("SELECT * FROM EMP")){rs => /* while (rs.next()){ print(rs.getString("empno") + " ") print(rs.getString("ename") + " ") print(rs.getString("job") + " ") print(rs.getString("mgr") + " ") print(rs.getString("hiredate") + " ") print(rs.getString("deptno") + " ") println(rs.getString("sal")) */ bmap(rs.next){ new Employee( rs.getInt("empno") ,rs.getString("ename") ,rs.getString("job") ,rs.getInt("mgr") ,rs.getDate("hiredate") ,rs.getInt("deptno") ,rs.getInt("sal") ) } } } }
結果は以下のように出力されます。
[Employee empno:1011,ename:安藤,job:null,mgr:0,hiredate:null,deptno:0,varsal:0] [Employee empno:7369,ename:SMITH,job:CLERK,mgr:7902,hiredate:1980-12-17,deptno:20,varsal:800] [Employee empno:7499,ename:ALLEN,job:SALESMAN,mgr:7698,hiredate:1981-02-20,deptno:30,varsal:1600] [Employee empno:7521,ename:WARD,job:SALESMAN,mgr:7698,hiredate:1981-02-22,deptno:30,varsal:1250] [Employee empno:7566,ename:JONES,job:MANAGER,mgr:7839,hiredate:1981-04-02,deptno:20,varsal:2975] [Employee empno:7654,ename:MARTIN,job:SALESMAN,mgr:7698,hiredate:1981-09-28,deptno:30,varsal:1250] [Employee empno:7698,ename:BLAKE,job:MANAGER,mgr:7839,hiredate:1981-05-01,deptno:30,varsal:2850] [Employee empno:7782,ename:CLARK,job:MANAGER,mgr:7839,hiredate:1981-06-09,deptno:10,varsal:2450] [Employee empno:7788,ename:SCOTT,job:ANALYST,mgr:7566,hiredate:1987-04-19,deptno:20,varsal:3000] [Employee empno:7839,ename:KING,job:PRESIDENT,mgr:0,hiredate:1981-11-17,deptno:10,varsal:5000] [Employee empno:7844,ename:TURNER,job:SALESMAN,mgr:7698,hiredate:1981-09-08,deptno:30,varsal:1500] [Employee empno:7876,ename:ADAMS,job:CLERK,mgr:7788,hiredate:1987-05-23,deptno:20,varsal:1100] [Employee empno:7900,ename:JAMES,job:CLERK,mgr:7698,hiredate:1981-12-03,deptno:30,varsal:950] [Employee empno:7902,ename:FORD,job:ANALYST,mgr:7566,hiredate:1981-12-03,deptno:20,varsal:3000] [Employee empno:7934,ename:MILLER,job:CLERK,mgr:7782,hiredate:1982-01-23,deptno:10,varsal:1300]
余白
EmployeeクラスのtoString() のオブジェクトをダンプする文字列を作る行が長いので、’+’のところで改行したら、出力された文字列が改行したところで切れてしまいました。
コメントを残す
コメントを投稿するにはログインしてください。