Scala+DBMS+Web スカラ座の夜

2010年11月19日

ScalaとJSPとデータベース

Filed under: — admin @ 11:35 AM

JSPのなかからScalaで記述したクラスを使うことを確かめてみました。

JSPページは、データベースをSelectしたScalaで記述したコードからのデータを JSP 側に渡して、JSP側でタグを付けするものです。

検索結果のレコードはjava.util.ArrayList を返し、要素はBeanに格納します。

このように実装した理由は、

1.ScalaのListではJava側から要素を取り出せなかったこと。

2.タプルだと格納できる要素数別のクラスとして返してくること

要素の取り出しがループで取れないこと

要素数に上限があることでデータベースのレコードを返すには問題があります。

3.JSON形式だとStringになってしまうのでデータベースのカラムの型が残らないこと

Beanのいいところは、表のカラム名を意識したコードが getEmpno のように書けること。ListやArrayだとどのカラムの値かはListやArrayに格納した実装を見ないとわからない。
Beanの課題は、事前にBeanクラスを作っておかなければならない。
Scalaで動的にクラスを定義する方法があるのか?
あるいは、別の方法が、、、

package SeeDo
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
){
    var Empno = empno
    var Ename = ename
    var Job = job
    var Mgr = mgr
    var Hiredate = hiredate
    var Deptno = deptno
    var Varsal = varsal

    def this() = this(0,null,null,0,null,0,0)

    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 setJob(value:String) = Job
    def setMgr(value:Int) = Mgr
    def setHiredate(value:Date) = Hiredate = value
    def setDeptno(value:Int) = Deptno = value
    def setVarsal(value:Int) = Varsal = value

    override def toString() =
        "[Employee empno:"+Empno+",ename:"+Ename+",job:"+Job+",mgr:"+Mgr+",hiredate:"+Hiredate+",deptno:"+Deptno+",varsal:"+Varsal+"]"
}
package SeeDo
import java.util.ArrayList
object Control {
    def using[A <: {def close():Unit},B](param:A)(f:A => B):B=
    try {
        f(param)
    }finally {
        param.close()
    }
    def bmap[T] (test: => Boolean)(block: => T):ArrayList[T] = {
        var ret = new ArrayList[T]
        while(test){
        	ret.add(block)
//        	println("size="+ret.size()+" bmap="+block)
        }
        ret
    }
}

データベースをSelectするクラスは、Scalaらしく findEmp関数になりました。

package SeeDo
import java.sql.{DriverManager, Connection, Statement, ResultSet,SQLException}
import java.util.ArrayList

class Emp {
    val jdbcURL = "jdbc:oracle:thin:@192.168.0.105:1521:ORCL"
    val user ="scott"
    val passwd ="tiger"
    def oracle() : ArrayList[Employee] = {
         Class.forName("oracle.jdbc.driver.OracleDriver").newInstance()
         var conn:Connection = null
         var list:ArrayList[Employee] = null
         try {
            conn = DriverManager.getConnection(jdbcURL,user,passwd)
            list = findEmp(conn)
        } catch {
              case e:SQLException => println("Database error "+e)
              case e => {
                println("Some other exception type:")
                e.printStackTrace()
              }
        } finally {
           conn.close()
        }
        list
     }
     def findEmp(conn:Connection): ArrayList[Employee] =
        Control.using (conn.createStatement){st =>
            Control.using (st.executeQuery("SELECT * FROM EMP")){rs =>
            	Control.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")
                 )
            }
        }
    }
}

JSP のなかで自分1レコード単位で記述したいので、for ループで処理します。

ScalaのEMP表のBeanオブジェクトがJSP ( Java ) のなかで機能してます。

<%@ page contentType="text/html;charset=MS932" %>
<%@ page import = "java.util.*" %>
<%@ page import = "scala.*" %>
<%@ page import = "SeeDo.*" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html LANG="ja-JP">
<head><title>Scala test</title></head>
<BODY><TABLE border='1'>
<%
	Emp o = new Emp();
	ArrayList list = o.oracle();
%>
<TR><TH>Class</TH><TD><%= o.getClass() %></TD></TR>
<TR><TH>Class</TH><TD><%= list != null ? list.getClass() : "-" %></TD></TR>
<TR><TH>ArrayList size</TH><TD><%= list != null ? list.size() : "-" %></TD></TR>
</TABLE><BR>
<TABLE border='2'>
<%
	for(int i=0;i < list.size() ;i++){
		Employee e = (Employee)list.get(i);
%>
<TR><TH><%=i%></TH>
<TD><%= e.getEmpno() %></TD>
<TD><%= e.getEname() %></TD>
<TD><%= e.getJob() %></TD>
<TD><%= e.getMgr() %></TD>
<TD><%= e.getHiredate() %></TD>
<TD><%= e.getDeptno() %></TD>
<TD><%= e.getVarsal() %></TD>
</TR>
<%	}
%>
</TABLE>
</BODY></html>

処理結果は、EMP表のデータをテーブル化します。

余談

Scalaが普及すれば JSP のように Scala と HTML をいっしょに記述できる SSP? なんてものがリリースされるのでしょうね。

Webデザイナの方ならTaglibの方がいいのかもしれませんが、Taglibを覚えたくないのでHTMLのなかに直接コードが書ける方が好みです。しかし、Webデザイナも JavaScript の知識なしにはWebもデザインできないでしょうからHTMLにコードがあることは違和感ではないと思う次第です。JSP なら Java と JavaScript とコードスタイルが違うので区別しやすいのですが、ScalaとJavaScriptだとどうなんでしょうね。

そういう実装を試みている方もいらっしゃいますが、是非とも本格的に利用できるものへ発展して欲しいです。

コメントはまだありません »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

コメントを投稿するにはログインしてください。

Powered by WordPress