SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新開発言語「Scala」の実体

Javaの限界を超えて実用化を目指す
新開発言語「Scala」のメリットとは~後編

キーワードは手軽さと拡張性

  • X ポスト
  • このエントリーをはてなブックマークに追加

簡単なデータ操作

 以下、Postgresのtest1テーブルからtest2テーブルへとすべての行をコピーするプログラムの例を見ていきましょう。Postgresのテーブル操作と、Scalaのプログラムは以下のとおりです(LIST31)。

LIST31:test1テーブルから、test2テーブルへコピー
●test1テーブルを作成するSQL
id bigserial プライマリキー
name text 名前
price integer 値段

CREATE TABLE test1
(
  id bigserial NOT NULL,
  "name" text,
  price integer,
  CONSTRAINT test1_pkey PRIMARY KEY (id)
)

●test2テーブルを作成するSQL
id Long プライマリキー(DB側で自動生成)
name string 名前
price int 値段

CREATE TABLE test2
(
  id bigserial NOT NULL,
  "name" text,
  price integer,
  CONSTRAINT test2_pkey PRIMARY KEY (id)
)

●先ほどのサンプルmain関数を、次に置き換えて実行する
/** main関数 */
override def main(args:Array[String]) = {
	val connection = connectPostgreSQL

	//一般的なSQLの実行方法
	val statementTest1 = connection.createStatement
	val resultSet = statementTest1.executeQuery("SELECT * FROM test1")

	//PrepareStatementを使用した実行方法
	val statementTest2 = connection.prepareStatement("INSERT INTO test2 (name, price) VALUES (?, ?)")

	while(resultSet.next){
		
		/////PrepareStatementの準備
		//test2テーブルの1番目のフィールド(name)に、test1テーブルからSELECTしたデータのnameフィールドの値をセット
		statementTest2.setString(1, resultSet.getString("name"))
		//test2テーブルの2番目のフィールド(price)に、test2テーブルからSELECTしたデータのpriceフィールドの値をセット
		statementTest2.setInt(2, resultSet.getInt("price"))

		/////PrepareStatementの実行
		statementTest2.executeUpdate
	}
	
	//リソースを閉じる
	resultSet.close
	statementTest1.close
	statementTest2.close

	closePostgreSQL(connection)

}

 Javaをお使いの方なら、すぐに理解できますね(O/Rマッパーに慣れた方々の目にはいささか原始的な例かもしれませんが)。test1テーブルからSELECTする部分は、java.sql.Statementオブジェクトを使用してSQL文を実行しています。また、test2テーブルへINSERTする部分は、java.sql.PrepareStatementオブジェクトを使用してSQL文を実行しています(実行速度や型を事前チェックできるという利点から、Javaでは、PrepareStatementオブジェクトの利用が推奨されています。こうした点はScalaでも同様です)。

 Scalaは、Java向けに書かれたソースコードだけでなく、Web上の情報や書籍など、言語についての情報資産もScalaの文法に読み替えるだけで理解できるということがお分かりいただけたのではないでしょうか。

Liftwebを用いた開発

 Liftweb(以下、Lift)とは、Scalaで書かれたWebフレームワークです。Lift自体がScalaを最大限活用して書かれており、高速かつ、スケーラブルなフレームワークになっており、Tomcat、Jettyなど、Javaで書かれたさまざまなAPサーバ上で動作します。

 また、snippetと呼ばれる独自のモデルを採用し、HTMLとScalaコードを簡単かつ上手に分割できる仕組みを持っています。また、標準機能としてAjaxを提供しているといった特徴もあります。

 JavaのフレームワークにはStrutsなどがありますが、Scalaと同じで高機能かつ手軽に扱え、生産性が高いことから、筆者らはLiftを採用しました。Liftについては、本稿では簡単なサンプルだけに留めておきますが、いずれ機会があれば実案件で用いた開発経験について紹介をしたいと思っています。

LiftのO/Rマッパークラスの使用例

 LiftはMavenでの開発を前提としているので、先ほどMavenで作成したLiftwebプロジェクトを基に説明します。

 Liftには、デフォルトでO/Rマッパーが付属しているので、¥todo¥src¥main¥scala¥com¥liftworkshop¥modelフォルダ以下に、各自が使用するテーブルごとのマッピングクラスを用意すると簡単にマッピングできます。ここでは、PostgreSQLへの接続例で使用したtest1テーブルを、LiftwebのO/Rマッパーを使用してマッピングするサンプルを示します。

 前述のmodelフォルダ内にTest1.scalaという名前のファイルを作成し、LIST32に示すサンプルコードを記述します。マッピングする際には、Liftweb側で用意されたテンプレート(Mapper)の中から、実際のテーブル構造に合ったものを継承してクラスを作成します。

LIST32:LiftのO/Rマッパーを使用する(¥todo¥src¥main¥scala¥com¥liftworkshop¥model ¥Test1.scala)
package com.liftworkshop.model

import _root_.net.liftweb.mapper._

//objectとする事で、アプリケーション全体で共有して使用出来る
object Test1Table extends Test1Table with KeyedMetaMapper[Long, Test1Table] {
	//データベースのテーブル名を指定する
	override def dbTableName = "test1"
}

class Test1Table extends KeyedMapper[Long, Test1Table] with CRUDify[Long, Test1Table]{

	def getSingleton = Test1Table
	def primaryKeyField = id	//プライマリキーを指定

	//以下、フィールドのマッピング
	//net.liftweb.mapper.MappedField クラスのサブクラスから型の合う物を選択して、DBの列の型と、lift上での型を合わせる
	object id extends MappedLongIndex(this)
	object name extends MappedText(this)
	object price extends MappedInt(this)
}

 継承するMapperによって使用できる関数が異なるため、特に問題がない限りはテーブル側にプライマリキーを付与して、KeyedMapperクラス(または、そのサブクラス)を継承することを推奨します。ここで、classとobjectに同一の名称(Test1Table)が付けられていることが気になったものと思います。Scalaでは、同一ファイル内でclassとobjectに同一の名称をつけることで、お互いのプライベート・クラスにアクセスできるようになります(コンパニオンオブジェクトと呼んでいます)。

次のページ
LiftのO/RマッパーでPostgreSQLに接続

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
新開発言語「Scala」の実体連載記事一覧

もっと読む

この記事の著者

株式会社パテントビューロ 三木隆史(ミキ タカフミ)

株式会社パテントビューロ所属。マネージャー業務と平行して、Webアプリケーション開発、自然言語系の研究開発を行なう。以前はC言語による組込開発。違和感なくScalaへ移行できたことや、ロジック部分に注力できる生産性の高さに驚いている。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

株式会社パテントビューロ 木村吉博(キムラ ヨシヒロ)

政府系研究機関での研究開発を経て、現在、株式会社パテントビューロにて、プログラミング(知財関連文書(SGML/XML)の変換バッチ処理のScalaでの記述など)を担当している。複雑でイレギュラーな記述も多々見られる大量の文書を相手にする際に、Scalaの書きやすさと高速性とに大いに助けられている。か...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4476 2009/11/19 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング