プロダクトレビュー
話題のO/Rマッピングツール「Cayenne」を使う
Cayenneを実際に使ってみる |
作成したアプリケーションを使い、実際にクエリなどを実行しながらCayenneの使い勝手を見ていきましょう。
■全件検索クエリの実行
Cayenneによって生成されたエンティティ・クラスを使用して、クエリ(SQLのSELECT文)を実行するにはDataContextクラスのクエリ発行用メソッドを使用します。用途に応じたいくつかのメソッドが用意されていますが、ここではシンプルなperformQuery()メソッドを使ってみます。
実際のサンプル・コードを見ていきましょう。最初にDataContextオブジェクトを取得します。ファクトリ・メソッドcreateDataContext()を利用します。cayenne.xmlを読み込んでDataContextオブジェクトの初期化を行います。
DataContext ctx = DataContext.createDataContext(); |
次にorg.objectstyle.cayenne.query.SelectQueryオブジェクトを生成します。SelectQueryオブジェクトはその名からも分かるとおりSQLのSELECTクエリを表現するオブジェクトです。最も単純な全件検索を行うためのSelectQueryの生成は、次のようにコンストラクタに対してDataObjectをjava.lang.Class型として指定するか、マッピング・ファイルで定義されている名前を指定します。
SelectQuery query = new SelectQuery(Employee.class); // Class型で指定する場合 |
クエリの実行はDataContextオブジェクトのperformQuery()メソッドを実行します。performQuery()メソッドはクエリの検索結果となるDataObjectが格納されたListオブジェクトを返します。
List list = ctx.performQuery(query); |
List型でDataObjectが取得できれば、Iteratorを使ってループ処理の中でgetXXX()メソッドを用いて各レコードのデータにアクセスすることができます。
Iterator i = list.iterator(); |
実行結果
John |
CayenneModelerで自動生成されたエンティティ・クラスには主キーに対するsetXXX()、getXXX() は作成されていません。Employeeクラスをエディタで開いて、次のようなgetId()メソッドを追加することで主キーの値を取得することができます。
public class Employee extends _Employee { |
Cayenneには自動的に主キーの値を生成する機能もありますが、今回は直接キー値を入力するので次のようにsetIdメソッドも追加しておきます(ObjectIdのimportを記述し忘れないようにしてください)。
public void setId(int id) { |
■主キーによる検索
全件検索の次は、主キーによって識別されるユニークなレコードを検索する例を試してみましょう。この場合はDataContextオブジェクトのregisteredObject()メソッドを使用します。先述したようにCayenneでは、主キーはObjectIdクラスのオブジェクトとして表現されます。registeredObject()メソッドはこのObjectIdを引数に取り、そのObjectIdによって識別される一意なエンティティ・オブジェクトを返します。
ObjectIdのコンストラクタにはエンティティ・クラスと主キーフィールド、主キーの値を渡します。以下のコード例ではEmployeeのIDが1であるObjectIdを用いてregisteredObject()メソッドを呼び出しています。
Employee emp = |
注:主キーが文字列型の場合には、ObjectId生成時にString型でキー値を渡します。
実行結果 John |
該当するレコードが存在し、エンティティ・オブジェクトが取得できれば、後はgetXXX()やsetXXX()メソッドを使ってデータ・アクセスを行うことができます。該当レコードがない場合、getXXX()メソッドの結果にはnullが返ります。
■WHERE句による条件検索
次にWHERE句による条件検索を試してみましょう。条件検索はorg.objectstyle.cayenne.exp.Expressionオブジェクトを引数に取るSelectQuery()メソッドを使用します。ExpressionオブジェクトはSQLのWHERE句の条件を表すために用意されており、fromString()メソッドを用いてSQLのWHERE句を直接記述することができます。
例えば名前の先頭が「E」であるレコードだけを取り出すには次のようにします。
Expression exp = Expression.fromString("name like 'E%'");
// Expressionの作成 List list = ctx.performQuery(query); |
実行結果
2:Elvin |
CayenneではExpressionオブジェクトを生成するためのヘルパー・クラスであるExpressionFactoryが用意されています。このクラスに用意されているメソッドを用いることで、よりオブジェクト指向的な感覚で条件式を指定することができます。例えば、以下のコードでは「dptCode = 'A01' AND name LIKE 'J%'」というSQLのWHERE句を実現しています。ここで使用しているsetQualifier()メソッドはクエリ・オブジェクトにExpressionをセットするためのメソッドであり、すでにExpressionが設定されたクエリにAND式やOR式を加えるためのandQualifier()やorQualifier()というメソッドも用意されています。
Expression exp1 = ExpressionFactory.matchExp("dptCode",
"A01"); |
ExpressionFactoryでほかにどのようなメソッドが用意されているかは、APIドキュメントを参照してください。
■リレーション関係にあるデータの取得
CayenneModelerを使ってリレーションの設定を行ったので、_Employeeクラスには、関連付いているDepartmentオブジェクトを返すgetEmpToDptRel()というメソッドが作成されています。そのため、以下のようにコーディングすることで、Employeeオブジェクトが参照するDepartmentオブジェクトのデータにアクセスすることができます。
// 全件検索のクエリを発行、Iteratorオブジェクトを取得済み |
実行結果
1:John:Development |
■ORDER BY句による並べ替え
ORDER BY句による並べ替えを実現するにはSelectQueryオブジェクトのaddOrdering()メソッドを使用します。引数に並べ替え対象となるフィールド名と、昇順であればtrue、降順であればfalseを渡します。以下のコード例ではEmployeeテーブルのName列を昇順に並べ替えています。
SelectQuery query = new SelectQuery("Employee"); |
実行結果
Elvin |
■新規レコードの挿入
ここまではSQLのSELECT文の機能を実現してきましたが、ここからは更新系のDML文(INSERT、UPDATE、DELETE)をどのように実現するのか紹介していきます。
新規レコードを挿入(SQLのINSERT文)するには、まずDataContextオブジェクトのcreateAndRegisterNewObject()メソッドを呼び出してメモリ上に新しいエンティティ・オブジェクトを生成します。この新しく生成したエンティティ・オブジェクトに対してsetXXX()メソッドを使用してフィールドの値をセットしていきます。新規レコードに必要な値をセットし終えたら、DataContextオブジェクトのcommitChanges()メソッドを呼び出すことによってエンティティ・オブジェクトの内容がDBに反映されます。
以下のコード例ではID列が「6」、Name列が「Alice」、DptCode列が「B01」の新しいレコードをテーブルに挿入しています。
Employee newEmp = (Employee)ctx.createAndRegisterNewObject("Employee"); |
更新系の操作を、もしロールバックする場合にはDataContextオブジェクトのrollbackChanges()メソッドを呼び出します。
■データの更新
既存のレコードのデータを更新する(SQLのUPDATE)場合には、取り出したエンティティ・オブジェクトのsetXXX()メソッドを使用して値を変更すればOKです。以下の例では、IDが1番のJohnのレコードを取り出し、名前を「Johnny」に、所属部署を「B01」に変更しています。変更後はcommitChanges()メソッドを呼び出して更新をDBに反映しておきます。
Employee emp = |
注:既存レコードの外部キーフィールドを更新する際には参照オブジェクト(上記例ではDepartmentオブジェクト)をリレーション・メソッドの引数に渡す必要があります。
■レコードの削除
最後にレコードの削除(SQLのDELETE文)です。レコードを削除するには、DataContextクラスに用意されているdeleteObject()メソッドを使用します。引数には削除の対象となるレコードに対応したエンティティ・オブジェクトを渡してやります。deleteObject()メソッドを実行した後にcommitChanges()メソッドを呼び出すことを忘れないようにしてください。
ctx.deleteObject(emp); |
■発行されるSQL文の確認
ここまでの簡単なサンプル・プログラムで理解できたと思いますが、O/Rマッピング・フレームワークを利用するアプリケーション開発者はSQL文を意識することなく、よりオブジェクト指向的なプログラミングによってRDBを扱うことができます。しかしO/Rマッピング・フレームワークの内部処理ではRDBに対してJDBCを通じてSQL文を発行しています。場合によっては実際に発行されているSQL文を確認したいこともあるでしょう。Cayenneで実際に発行されるクエリのSQL文を確認するにはQueryインターフェイスで定義されているsetLoggingLevel()メソッドを使用します。このメソッドの引数にはLog4jのLevelオブジェクト(WARN)を渡します。
query.setLoggingLevel(org.apache.log4j.Level.WARN); |
更新系のSQL文(INSERT、UPDATE、DELETE)の確認はcommitChanges()メソッドを呼び出す際に、上記同様Level.WARNを引数として渡してやってください。
ctx.commitChanges(org.apache.log4j.Level.WARN); |
こうすることで、標準出力のコンソールにCayenneがデータベースに対して発行したSQL文が表示されるようになります。
◆
最近話題のO/Rマッピング・フレームワークCayenneの仕組みと簡単な使い方をざっと紹介してきましたが、いかがでしたか? この記事では詳細な説明をすることはできませんでしたが、Cayenneを使ってみる取っ掛かりにはなったと思います。ぜひこれを機会にアプリケーションでのCayenneの活用を試してみてください。また、ほかのO/Rマッピング・フレームワークも試しながら、相違点や使いやすさなどを比べてみるのも面白いでしょう。ソースコードも公開されているので、オリジナルのO/Rマッピング・フレームワークを作成する際のヒントにすることもできるでしょう。
3/3 |
INDEX |
||
話題のO/Rマッピングツール「Cayenne」を使う | ||
Page1 Cayenneの構造と仕組み |
||
Page2 サンプルアプリケーションを作成する |
||
Page3 Cayenneを実際に使ってみる |
- 実運用の障害対応時間比較に見る、ログ管理基盤の効果 (2017/5/9)
ログ基盤の構築方法や利用方法、実際の案件で使ったときの事例などを紹介する連載。今回は、実案件を事例とし、ログ管理基盤の有用性を、障害対応時間比較も交えて紹介 - Chatwork、LINE、Netflixが進めるリアクティブシステムとは何か (2017/4/27)
「リアクティブ」に関連する幾つかの用語について解説し、リアクティブシステムを実現するためのライブラリを紹介します - Fluentd+Elasticsearch+Kibanaで作るログ基盤の概要と構築方法 (2017/4/6)
ログ基盤を実現するFluentd+Elasticsearch+Kibanaについて、構築方法や利用方法、実際の案件で使ったときの事例などを紹介する連載。初回は、ログ基盤の構築、利用方法について - プログラミングとビルド、Androidアプリ開発、Javaの基礎知識 (2017/4/3)
初心者が、Java言語を使ったAndroidのスマホアプリ開発を通じてプログラミングとは何かを学ぶ連載。初回は、プログラミングとビルド、Androidアプリ開発、Javaに関する基礎知識を解説する。
|
|