私にとって2005年は不思議な年でした。私はこの10年来初めて、Java以外の言語による本格的な開発を始めました。最初の部分を処理している間、ビジネス・パートナーと私は、素早く概念検証することには非常な成功を収めました。しかし私達は岐路に立ったのです。つまり、Java開発を続けるべきか、あるいは何か、過激で新しいものに切り換えるべきかという選択を下す必要がありました。Javaにとどまる理由としては、次のように幾つかを挙げることができます。
- (新しい言語では)まったく初めから学ばなければならない
- Javaのプログラミング・コミュニティーは非常に強力なため、切り換えることを顧客に納得させるのは難しい
- (他の言語では)Javaのように何千ものオープンソース・プロジェクトから自由に選択することは不可能
しかし私達は他の言語で開発を行うという考えを捨てず、Ruby言語上に構築されたWebアプリケーション・フレームワークである、Ruby on Railsでアプリケーションの構築を始めました。そして予想もしなかった成功を収めたのです。それ以来私は、うまく時間を切り分けて、Javaの指導と開発(ほとんどはHibernateとSpringに関するもの)と、Rubyの指導と開発の両方を行うようになりました。そして、時には他の手法や言語を学ぶことが非常に重要だと信ずるようになりました。その理由として、下記を挙げることができます。
- Javaはどんな問題にも完璧な言語というわけではない
- 新しい考え方をJavaプログラミングに反映することができる
- 他のフレームワークもJavaフレームワークと同じ構築形態をとりつつある
こうした考え方を示すためのシリーズの第1回として、今回はRuby on Railsのパーシスタンス・アーキテクチャーの核心である、アクティブ・レコードを見て行きます。また、スキーマ・マイグレーションについても解説します。
正直に言うと、私はRailsを最初に試した時、かなり傲慢でした。アクティブ・レコードなど丸で役に立たないと思い込んでいたのですが、実は一部の問題に対しては、あらゆるものが用意されていることを知ったのです。
アクティブ・レコードがパーシスタンスをどう処理するかを学ぶためには、少しコードを書いてみることが一番です。この例ではMySQLデータベースを使っていますが、少し変更すれば、このコードを他のデータベースにも使うことができます。
アクティブ・レコードを最も簡単に使うには、何と言ってもRuby on Railsを使うことです。この記事のコードを追うためには、Ruby on Railsをインストールする必要があります(参考文献)。
次に、プロジェクトを作成します。Railsで新しいプロジェクトを作成するためのディレクトリーに行き、下記をタイプします。
rails email_list |
Railsがプロジェクトを作成すると、しゃれたRailsツールからアクティブ・レコードを使うことができます。残るステップは、データベースをコンフィギュレーションすることです。email_list_developmentというデータベースを作成し、config/database.ymlファイルを編集して、次のようにします(ユーザー名とパスワードをタイプすることを忘れないでください)。
development: adapter: mysql database: email_list_development host: localhost username: root password: |
この記事では、テスト環境や実稼働環境を気にする必要はないため、必要なコンフィギュレーションはこれだけです。これで準備完了です。
Hibernateでは、通常は最初にJavaオブジェクトの開発から始めますが、これはHibernateが『マッピング・フレームワーク』であるためです。Hibernateの世界では、オブジェクト・モデルが中心となります。アクティブ・レコードは、『ラッピング・フレームワーク』です。そのため、まずデータベース・テーブルを作成することから始めます。アクティブ・レコードの世界では、リレーショナル・スキーマが中心なのです。データベース・テーブルを作成するためには、GUIを使用するか、あるいは下記のようなスクリプトをタイプします。
CREATE TABLE people ( id int(11) NOT NULL auto_increment, first_name varchar(255), last_name varchar(255), email varchar(255), PRIMARY KEY (id) ); |
次に、app/models/person.rbというファイルを作成します。これを、次のようにします。
class Person < ActiveRecord::Base end |
このRubyコードは、ActiveRecord::Baseというスーパークラスを持つPersonというコードを作成します。(とりあえず、BaseはJavaクラスのようなものであり、ActiveRecordはJavaパッケージのようなものだと思ってください。)驚くなかれ、たったこれだけで、非常に多くのことができるのです。
これで、アクティブ・レコードのコンソール内からPersonを操作することができます。このコンソールを使うと、データベースを持つオブジェクトを、Rubyインタープリターの中から使えるのです。下記をタイプします。
ruby script/console. |
今度は新しいpersonを作成します。下記のRubyコマンドをタイプします。
>> person = Person.new >> person.first_name = "Bruce" >> person.last_name = "Tate" >> person.email = "bruce.tate@nospam.j2life.com" >> person.save >> person = Person.new >> person.first_name = "Tom" >> person.save |
これまでアクティブ・レコードを使ったことのない人にとっては、新鮮に、そして興味深く見えるのではないでしょうか。この小さな例の中には、2つの重要な機能、つまり『コンフィギュレーションよりも規則優先(convention over configuration)』と『メタプログラミング』が含まれています。
『コンフィギュレーションよりも規則優先』では、自分が選択した名前に基づいてコンフィギュレーションを推測できるため、面倒な繰り返しを避けることができます。上記では何らマッピングをコンフィギュレーションする必要がありませんでしたが、これはデータベース・テーブルの構築をRailsの命名規則に従って行ったためです。こうした名前の主なものとしては、下記があります。
- モデル・クラス名(EmailAccountなど)は、CamelCaseであり、英語の単数です。
- データベース・テーブル名(email_accounts)は、単語間に下線(underscore)を使用し、英語の複数です。
- プライマリー・キーは、リレーショナル・データベースの行を固有識別します。アクティブ・レコードは、プライマリー・キーとしてidを使用しています。
- 外部キーは、データベース・テーブルを連結します。アクティブ・レコードは、英語の単数と_id接尾辞を持つ外部キー(person_idなど)を使用しています。
Railsの命名規則に従う場合には、『コンフィギュレーションよりも規則優先』によって一層高速にすることができますが、この命名規則をオーバーライドすることもできます。例えば、次のようなpersonが可能です。
class Person < ActiveRecord::Base set_primary_key "ssn" end |
ですから『コンフィギュレーションよりも規則優先』によって不必要な制限が課されることはありません。単純に、一貫した命名方式を使えば大きな見返りが得られるのです。
メタプログラミングも、アクティブ・レコードの持つ、もう1つの重要機能です。アクティブ・レコードでは、Rubyのリフレクション機能とメタプログラミング機能を多用しています。メタプログラミングというのは単純に、「プログラムを書く、あるいは変更する」プログラムを書くことです。この場合では、Baseクラスが、データベース中の全カラムに対してpersonクラスに属性を追加しています。何らコードを書いたり生成したりする必要はありませんでしたが、person.first_nameやperson.last_name、person.emailなどを使うことができています。メタプログラミングについては、この先でさらに詳しく説明します。
アクティブ・レコードには、Javaフレームワークに無いような機能も幾つか含まれています。例えば『モデル・ベース検証(model-based validation)』です。モデル・ベース検証を利用すると、データベース内のデータの一貫性を保証することができます。person.rbを次のように変更します。
class Person < ActiveRecord::Base validates_presence_of :email end |
コンソールから、(personは変更されているので)personをロードし、下記のRubyコマンドをタイプします。
>> load 'app/models/person.rb' >> person = Person.new >> person.save |
Rubyがfalseを返します。このように、任意のRubyプロパティーに対するエラー・メッセージを見ることができます。
>> puts person.errors[:email] can't be blank |
ここまではJavaフレームワークでは普通見られないような機能を見てきましたが、まだ信じていない人もいるかも知れません。実は、データベース・アプリケーションのプログラミングで最も難しいのは、リレーションシップの管理部分であることが多いものです。そうした場合にアクティブ・レコードが役立つことをお見せしましょう。addressesという、別のテーブルを作成します。
CREATE TABLE addresses ( id int(11) NOT NULL auto_increment, person_id int(11), address varchar(255), city varchar(255), state varchar(255), zip int(9), PRIMARY KEY (id) ); |
プライマリー・キーと外部キーについてはRailsの規則に従ったので、コンフィギュレーションは無料で手にすることができます。今度はアドレスのリレーションシップをサポートするようにperson.rbを変更します。
class Person < ActiveRecord::Base has_one :address validates_presence_of :email end |
そしてapp/models/address.rbを作成します。
class Address < ActiveRecord::Base belongs_to :person end |
Rubyが初めての読者のために、この構文を説明しましょう。belongs_to :personは、シンボルをパラメーターとするメソッドなのです。メソッド定義ではありません。(とりあえず、シンボルは不変ストリングだと考えてください。)belongs_toメソッドは、addressにpersonという関連付けを追加するメタプログラミング・メソッドです。この動作を見てみましょう。コンソールが実行している場合には一旦コンソールを終了し、ruby script/consoleを使って再起動します。次に、下記のコマンドを入力します。
>> person = Person.new >> person.email = "bruce@tate.com" >> address = Address.new >> address.city = "Austin" >> person.address = address >> person.save >> person2 = Person.find_by_email "bruce@tate.com" >> person2.address.city => "Austin" |
リレーションシップを説明する前に、findメソッド、find_by_emailをもう一度見てください。アクティブ・レコードは、各属性に対してカスタム・ファインダーを追加します。(この説明は少し簡略化しすぎていますが、とりあえずはこの説明で我慢してください。)
さて、最後のリレーションシップを見てください。has_one :addressはAddressというタイプのインスタンス変数をpersonに追加します。このaddressも永続性を持っています(コンソールからAddress.find_firstを入力すれば検証することができます)。つまりアクティブ・レコードは、積極的にリレーションシップを管理しています。
また、単純な1対1の関係だけに制限されているわけではありません。person.rbを次のように変更します。
class Person < ActiveRecord::Base has_many :addresses validates_presence_of :email end |
addressをaddressesと複数にすることを忘れないでください。今度はコンソールから、下記のコマンドをタイプします。
>> load 'app/models/person.rb' >> person = Person.find_by_email "bruce@tate.com" >> address = Address.new >> address.city = "New Braunfels" >> person.addresses << address >> person.save >> Address.find_all.size => 2 |
person.addresses < addressコマンドは、addressesの配列にaddressを追加します。アクティブ・レコードは、(ご想像した通り)2番目のaddressをpersonに追加しています。データベースには、もう1つのレコードがあることが検証されています。つまりhas_manyはhas_oneのように動作しますが、各Personにaddresesの配列を追加するのです。実際、アクティブ・レコードを使うと、様々なリレーションシップを持つことができます。下記はその例です。
- belongs_to(多対1)
- has_one(1対1)
- has_many(1対多)
- has_and_belongs_to_many(多対多)
- inheritance 英語のまま
- acts_as_tree英語のまま
- acts_as_list英語のまま
- composition(1つ以上のクラスを1つのテーブルにマップする)
アクティブ・レコードを学ぶことによって、私はパーシスタンスに関する理解を大いに深めることができました。そして、ラッピング手法は必ずしも劣った方法ではなく、単に異なるだけなのだ、ということを学びました。私はまだまだ、一部の問題(cruftyレガシー・スキーマなど)に関するマッピング・フレームワークについて学ぶ必要があります。アクティブ・レコードが対象とするニッチは非常に大きく、今後アクティブ・レコードがサポートするマッピングが改善されるにつれ、アクティブ・レコードも改善されて行くと思います。
また私は、パーシスタンス・フレームワークが効果的であるためには、その言語の特性を生かすべきだということも学びました。Rubyは非常に反映的(reflective)であり、ある形式のリフレクションを使ってデータベース・システム・テーブルの定義をクエリーします。
しかし、この後すぐに分かる通り、私はアクティブ・レコードだけでRailsのパーシスタンスを経験したわけではありません。
私はアクティブ・レコードを学ぶにつれ、2つの問題に苦しむようになりました。アクティブ・レコードを使うと、create-table SQLスクリプトを構築せざるを得ず、そのため個々のデータベース実装に拘束されてしまうのです。また開発中には頻繁にデータベースを削除する必要がありましたが、そのため、大きな変更を行う度に全テスト・データをインポートせざるを得ませんでした。私は、実稼働後の最初の変更を躊躇していました。そこに、実稼働データベースへの変更を処理するRuby on Railsのソリューションである、マイグレーション(migration)が登場するのです。
Railsのマイグレーションでは、データベースに対する大きな変更毎にマイグレーションを作成することができます。この記事のアプリケーションでは、2つのマイグレーションを持つことができます。この実際を見るために、2つのファイルを作成します。まず、db/migrate/001_initial_schema.rbというファイルを作成し、次のようにします。
class InitialSchema < ActiveRecord::Migration
def self.up
create_table "people" do |table|
table.column "first_name", :string, :limit => 255
table.column "last_name", :string, :limit => 255
table.column "email", :string, :limit => 255
end
end
def self.down
drop_table "people"
end
end
|
そして002_add_addresses.rbに、これを追加します。
class AddAddresses < ActiveRecord::Migration
def self.up
create_table "addresses" do |table|
table.column "address", :string, :limit => 255
table.column "city", :string, :limit => 255
table.column "state", :string, :limit => 2
table.column "zip", :string, :limit => 10
table.column "person_id", :integer
end
Person.find_all.each do |person|
person.address = Address.new
person.address.address = "Not yet initialized"
person.save
end
end
def self.down
drop_table "addresses"
end
end
|
下記をタイプすると、マイグレート・アップすることができます
rake migrate |
rakeはJavaのantのようなものです。Railsには、マイグレーションを実行するmigrateというターゲットがあります。このマイグレーションは、スキーマ全体を追加します。とりあえず何人かの人(person)を追加しますが、まだアドレスについては気にしないでください。
ここで仮に、皆さんがひどい間違いをしてしまい、以前のバージョンにマイグレート・ダウンしなければならない、と思ってください。下記をタイプします。
rake migrate VERSION=1 |
このコマンドは、最初のマイグレーション(ファイル名の中のバージョン番号で指定されています)に対してAddAddresses.downメソッドを適用しています。マイグレート・アップでは、必要なマイグレーション全てに対して、数字の順にupメソッドを呼びます。マイグレート・ダウンでは、逆の順でdownメソッドを呼びます。データベースを見ると、peopleテーブルしかありません。アドレスが削除されています。つまりmigrateを使うと、必要に応じてマイグレート・アップ、マイグレート・ダウンができるのです。
マイグレーションにはもう1つの機能、つまりデータ処理があります。再度、下記をタイプしてマイグレート・アップします。
rake migrate |
このコマンドはAddAddresses.upを実行し、実行する中で、各PersonオブジェクトをActive Recordアドレスで初期化します。この振る舞いは、コンソールで確認することができます。Personオブジェクトを追加すると、Addressオブジェクトも追加されています。新しいコンソールを開き、人(person)の数とアドレス・データベース行数を数えます(下記)。
>> Address.find_all.size >> Person.find_all.size |
つまり、マイグレーションは、スキーマとデータの両方を器用に処理するのです。今度は、こうした概念が、Javaの場合とどのように関連するのかを見てみましょう。
Java技術でのパーシスタンスの歴史は、魅力的であると同時に悲劇的であり、そして希望に満ちたものでした。長年、Java言語が選択したコア・パーシスタンス・フレームワーク(つまりEJB(Enterprise JavaBeans)のバージョン1と2)は不適切であったため、アプリケーションは苦闘を余儀なくされ、ユーザーは幻滅しました。HibernateとJDO(Java Data Objects)は、どちらも新しいEJBパーシスタンスと共通パーシスタンス標準の基礎をなすものですが、これらによってJavaコミュニティーの中にORM(object-relational mapping)が生まれ、今やJavaを使うこと自体がずっと楽しいものになりました。
JavaコミュニティーとORM(別名マッピング・フレームワーク)との恋愛関係は7年間も続いています。基本的にマッピングの手法を利用すると、ユーザーはJavaオブジェクトとデータベース・オブジェクトとを独立に定義でき、また両者の間にマップを構築することができます。これを図1に示します。
図1. マッピング・フレームワーク
Java言語は、まず統合言語であることが多いため、マッピングはcruftyレガシー・システムを統合する際に重要な役割を果たします(そのシステムが、たとえオブジェクト指向言語が登場するずっと以前に作られたものであっても)。今やJavaコミュニティーでは、信じられないほどマッピングを多用しています。今日では、典型的なJavaプログラマーは、ごく基本的な問題を解決するためにさえORMを利用しています。マッピングが好まれる理由は、Javaのマッピング実装が、その対抗となる手法、つまりラッピング・フレームワークよりも優れているためです。
しかし、だからといってラッピング・フレームワークの力を過小評価すべきではありません。ラッピング・フレームワークは、データベース・テーブルの周りを薄いラッパーで覆い、データベース行をオブジェクトに変換するのです(図2)。
図2. ラッピング・フレームワーク
マップが必要のない場合には、マッピング・レイヤーは大きなオーバーヘッドを生じますが、Javaのラッピング・フレームワークは復活の兆しを見せているようです。Springフレームワークでは、JDBCラッピングを行うことができ、またエンタープライズ統合に必要なあらゆる機能を統合することができます。またiBATISは、テーブルではなくSQLステートメントの結果をラップすることができます(参考文献)。どちらのフレームワークも、私の意見では素晴らしい機構であり、まだ過小評価されていると思います。通常のJavaマッピング・フレームワークでは、Javaのラッピング・フレームワークでは手動で行わざるを得ないことを、自動的に行うことができるのです。
Javaプラットフォームは、既に最先端のマッピング・フレームワークを誇っています。しかし私は、今やJavaプラットフォームには革新的なラッピング・フレームワークが必要だと思っています。アクティブ・レコードは、言語機能によってRailsクラスをオンザフライで拡張します。Javaフレームワークでも、アクティブ・レコードが提供するものの一部をシミュレートすることはできるかも知れません。しかしアクティブ・レコードのようなものを作ることは非常に難しく、現在のJava規則の一部を破る必要があるかも知れません。例えば次のような規則です。
-
パーシスタンス・ソリューションは、Java POJO(plain old Java object: 昔ながらの単純Javaオブジェクト)のみを対象にすべきである。まず何よりも、データベースの内容を基にプロパティーを作成することは困難です。ドメイン・オブジェクトには別のAPIがあるかも知れません。person.get_nameを呼んでプロパティーを設定する代わりに、person.get(name) を使う必要があるかも知れません。静的型チェックというコストを払った上で、データベースに駆動されるメタデータで構成されたクラスを得るのです。
-
パーシスタンス・ソリューションは、XMLまたは注釈(annotation)でコンフィギュレーションを表現する必要がある。Railsはこれとは逆に、意味のあるデフォルトを使った命名規則を強制しているため、ユーザーは大幅に繰り返しを減らすことができます。またデフォルトは、必要に応じて追加のコンフィギュレーション・コードを使ってオーバーライドできるため、コストは大したことはありません。Javaフレームワークは、『コンフィギュレーションよりも規則優先』というRailsでの仕組みを容易に採用することができます。
-
スキーマ・マイグレーションは、パーシスタント・ドメイン・モデルによって駆動すべきである。Railsはマイグレーションに関して、これとは逆です。これによる大きな利点は、データとスキーマの両方をマイグレーションできることです。またRailsでは、マイグレーションによって、リレーショナル・データベースのベンダーに依存する必要がなくなります。またRailsの戦略では、パーシスタンス戦略をスキーマ・マイグレーションの問題から分離することができます。
Railsは、Javaフレームワークの設計者が神聖なものと思いがちな、そして長年に渡って確立されてきた、こうした規則を破っています。Railsは作業スキーマとして始まっており、スキーマを反映してモデル・オブジェクトを構築します。Javaのラッピング・フレームワークでは、同じ手法は無理かも知れません。その代わり、Javaが静的型定義をサポートしているとことを利用して(また、こうした型を認識し、またコード完了などの機能を提供するツールを利用して)、作業モデルとして開始し、Javaのリフレクションと素晴らしいJDBC APIを使って、この作業モデルをデータベースにまで動的に強制することができます。
新しいJavaラッピング・フレームワークとして洗練されつつあるものに、Geert Bevin の作成によるRIFE(そして、そのサブプロジェクトであるRIFE/Crud)があります(参考文献)。RIFEのパーシスタンスの中核には、次のような3つの主なレイヤーがあります。図3は、これを示したものです。
- 単純なJDBCラッパー。テンプレートによってコールバック風のJDBC実装を提供します。
- データベースから独立した一連のSQLビルダー。オブジェクト指向の手法によってクエリーを構築します。
- タイプ・マッピング・レイヤー。ほとんどのSQL型を、最も関連したJava型に変換します。
図3. RIFEフレームワークでのパーシスタンス・アーキテクチャー
これらのレイヤーは、『クエリー・マネージャー』という、簡略化されたAPIが使用します。このAPIを利用すると、パーシスタンス関連のタスク(保存や更新など)に直感的にアクセスすることができます。このAPIの中の1つはJDBC専用であり、その他は、RIFEのコンテンツ管理フレームワークに関連するメタデータを検出するためのAPIに似たものとして動作します。
RIFE/Crudは、こうしたフレームワークの最上部に位置する非常に小さなレイヤーとして、すべてを一つにまとめています。RIFE/Crudは、制約(constraint)とbeanプロパティーを使って、アプリケーションのユーザー・インターフェースや、サイトの構造、パーシスタンス・ロジック、ビジネス・ロジックなどを自動的に構築します。RIFE/Crudは、RIFEのメタデータ機能を最大限に利用してインターフェースや関連APIを生成しますが、相変わらずPOPJに対して機能します。RIFE/Crudは、APIやテンプレート、コンポーネント・アーキテクチャーなどの中で明確に定義されるRIFEの統合ポイントを利用して、完全に拡張することができます。
クエリー・マネージャーのAPIは、驚くほど単純です。RIFEのパーシスタンス・モデルの実際を紹介しましょう。今ここで仮にArticleクラスがあり、その周りにテーブル構造を作り、データベースに対して2つのarticleを永続させたい、としましょう。このようなデータ・ソースに対して、下記のコードを使うとクエリー・マネージャーが得られます。
GenericQueryManager manager = GenericQueryManagerFactory.
getInstance(datasource, Article.class);
|
次に、クエリー・マネージャーをインストールすることによって、データベースの中にテーブル構造を作ります。
manager.install(); |
これで、クエリー・マネージャーを使ってデータベースにアクセスすることができます。
Article article1 = new Article("title");
Article article2 = new Article("othertitle");
manager.save(article1);
manager.save(article2);
List articleList = manager.restore(
manager.getRestoreQuery().where("title", "=", "othertitle"));
|
つまりRIFEフレームワークはアクティブ・レコードと同様、『コンフィギュレーションよりも規則優先』を使うのです。Articleは、idというIDプロパティーをサポートする必要があります。あるいは、ユーザーがRIFEのAPIを使ってIDプロパティーを規定する必要があります。またRIFEは、アクティブ・レコードと同じくネイティブ言語の機能を使います。この場合、相変わらずラッピング・フレームワークはありますが、スキーマがモデルを駆動するのではなく、モデルがスキーマを駆動します。そして、(RIFEによる解決が必要な多くの問題に対して)大部分のオブジェクト・リレーショナル・マッパーよりも、APIはずっと単純です。優れたラッピング・フレームワークは、大いにJavaに役立つのです。
アクティブ・レコードは、Javaではない言語で書かれたパーシスタンス・モデルであり、その言語の機能を大いに活用しています。今まで知らなかった人達も、ラッピング・フレームワークによってどんなことができるのか、この記事から学ぶことができたと思います。また、ここではマイグレーションについても学びました。理論的には、Javaフレームワークでもマイグレーションの概念を採用できるはずです。もちろんマッピング・フレームワークも有効なものですが、この記事から学んだことを利用してJava言語での伝統的なマッピング・ソリューションを超え、新たなラッピングの波をとらえて欲しいと思います。次回は、Web開発における継続ベース(continuation-based)の手法について解説する予定です。
学ぶために
- この記事の著者によるBeyond Java(Bruce Tate著、2005年O'Reilly刊)は、Javaコードの台頭と停滞について、また一部ニッチ領域においてJavaプラットフォームに対抗しうる技術について解説しています。
- 「Rolling with Ruby on Rails」と「Learn all about Ruby on Rails」を読んで、インストール方法を含めてRubyとRailsについて学んでください。
- 「Ruby on Rails and J2EE: Is there room for both?」(Aaron Rustad著, developerWorks, 2005年7月)は、アーキテクチャー上の主な特徴に関して、Railsと伝統的なJ2EEフレームワークとを比較対照しています。
- 「Ruby off the Rails」(Andrew Glover著, developerworks, 2005年12月)の中で、Andrew Gloverは流行の表層を掘り下げ、Rubyそのもので何ができるかを解説しています。
-
Active Recordは、Ruby on Railsフレームワーク用のパーシスタンス・フレームワークです。
- 3回シリーズのチュートリアル、「Improve persistence with Apache iBATIS and Derby」(Daniel Wintschel著, developerWorks, 2006年1月)では、最高のJavaラッピング・フレームワークの1つであるiBATISのすべてを学ぶことができます。
- 「The Spring series, Part 2: When Hibernate meets Spring」(Naveen Balani著, developerWorks, 2005年8月)は、Hibernateを使う上での最高の組み合わせ、つまりSpringとHibernateとの組み合わせについて解説しています。
-
Java technologyゾーンには、Javaプログラミングのあらゆる面を網羅した記事が他にも豊富に用意されています。
製品や技術を入手するために
-
RIFEフレームワークを入手してください。RIFEは、非Java言語の持つ、過激な手法の一部を採り入れています。
- オープンソースのRuby on Rails Webフレームワークをダウンロードしてください。
- RubyプロジェクトのWebサイトからRubyを入手してください。
議論するために
-
developerWorks blogsからdeveloperWorksコミュニティーに加わってください。

Bruce Tate氏は、独立コンサルタント兼執筆者です。彼は12年間IBMに勤め、Javaのproof-of-conceptチームなどの様々な仕事に携わりました。Tate氏は、IBMで、Austinのあるスタートアップのためにソリューション開発組織を運営していましたが、その後IBMを退職し、J2Life, LLC という独自の事業を立ち上げました。彼は、Bitter Javaを含め、Javaアンチパターンに関する3冊の書籍を執筆しました。彼の連絡先は、bruce.tate@j2life.comです。