atwiki-logo
  • 新規作成
    • 新規ページ作成
    • 新規ページ作成(その他)
      • このページをコピーして新規ページ作成
      • このウィキ内の別ページをコピーして新規ページ作成
      • このページの子ページを作成
    • 新規ウィキ作成
  • 編集
    • ページ編集
    • ページ編集(簡易版)
    • ページ名変更
    • メニュー非表示でページ編集
    • ページの閲覧/編集権限変更
    • ページの編集モード変更
    • このページにファイルをアップロード
    • メニューを編集
    • 右メニューを編集
  • バージョン管理
    • 最新版変更点(差分)
    • 編集履歴(バックアップ)
    • アップロードファイル履歴
    • ページ操作履歴
  • ページ一覧
    • ページ一覧
    • このウィキのタグ一覧
    • このウィキのタグ(更新順)
    • おまかせページ移動
  • RSS
    • このウィキの更新情報RSS
    • このウィキ新着ページRSS
  • ヘルプ
    • ご利用ガイド
    • Wiki初心者向けガイド(基本操作)
    • このウィキの管理者に連絡
    • 運営会社に連絡(不具合、障害など)
ページ検索 メニュー
Unofficial DB2 Wiki
  • ウィキ募集バナー
  • 目安箱バナー
  • 操作ガイド
  • 新規作成
  • 編集する
  • 全ページ一覧
  • 登録/ログイン
ページ一覧
Unofficial DB2 Wiki
  • ウィキ募集バナー
  • 目安箱バナー
  • 操作ガイド
  • 新規作成
  • 編集する
  • 全ページ一覧
  • 登録/ログイン
ページ一覧
Unofficial DB2 Wiki
ページ検索 メニュー
  • 新規作成
  • 編集する
  • 登録/ログイン
  • 管理メニュー
管理メニュー
  • 新規作成
    • 新規ページ作成
    • 新規ページ作成(その他)
      • このページをコピーして新規ページ作成
      • このウィキ内の別ページをコピーして新規ページ作成
      • このページの子ページを作成
    • 新規ウィキ作成
  • 編集
    • ページ編集
    • ページ編集(簡易版)
    • ページ名変更
    • メニュー非表示でページ編集
    • ページの閲覧/編集権限変更
    • ページの編集モード変更
    • このページにファイルをアップロード
    • メニューを編集
    • 右メニューを編集
  • バージョン管理
    • 最新版変更点(差分)
    • 編集履歴(バックアップ)
    • アップロードファイル履歴
    • ページ操作履歴
  • ページ一覧
    • このウィキの全ページ一覧
    • このウィキのタグ一覧
    • このウィキのタグ一覧(更新順)
    • このページの全コメント一覧
    • このウィキの全コメント一覧
    • おまかせページ移動
  • RSS
    • このwikiの更新情報RSS
    • このwikiの新着ページRSS
  • ヘルプ
    • ご利用ガイド
    • Wiki初心者向けガイド(基本操作)
    • このウィキの管理者に連絡
    • 運営会社に連絡する(不具合、障害など)
  • atwiki
  • Unofficial DB2 Wiki
  • Cayenne memo

Unofficial DB2 Wiki

Cayenne memo

最終更新:2007年02月05日 17:08

db2

- view
管理者のみ編集可

Cayenneとは?


  • Cayenneは、O/R Mapping Tool/Libraryの一種
  • ライセンスはOpenSource(The ObjectStyle Group Software License, version 1.1)
  • Modelerと呼ばれるGUIが秀逸
  • DB2,Derby(Cayenne 1.2から)他、多くのRDBMSに対応している

大まかな作業の流れ

A. DB側を先に作成して、Java側に反映させる場合

  1. DBMS上で表を作成する。リレーションも作成する
  2. Cayenne Modelerを起動し、DataDomainを作成
  3. DataDomain上に、DataNode(DBへの接続設定)を作成
  4. ModelerのReengineer機能でDBの表やリレーションを読み出し、ObjEntity(Java Classに対応)とDbEntity(表に対応)を作成する
  5. Generate ClassesでJavaのソースコードを生成
  6. Generate Database Schemaで、"Create Primary Key Support"のみ にチェックを入れてDDLを作成し(シーケンス文が作成される)、DB上で実行する

B. Modeler上でEntityを作成し、それをDBMSに反映させる場合

  1. Modelerで、Data Entityを定義する
  2. Entityのリレーションを作成する
  3. ClassをGenerateする
  4. DDL(DB Schema)をGenerateする

リレーション

  • DBMS側で外部キー制約を作成しておくと、Cayenne Modelerが読み取る際にリレーションを作成してくれる
  • ただし、参照する親表の列はプライマリーキー列 でなければ、リレーションは作成されないようだ。(単にユニーク制約がある列への外部キーでは駄目なようだ)
  • これはおそらくCayenneにとっては、外部キー=他のEntityへのポインタなのでポイントする先は当然ObjectIDであるべきという事なのだと思われる

クエリ(Query)の構築


Queryの種類


Queryは、SelectQuery ,SQLTemplate ,ProcedureQuery の三種類

SelectQuery

  • SQL文を使わない(DBMS Portableな)クエリ
  • このQueryが基本で、SelectQueryが使えない場合のみ他のQueryを使うべきというのが作者の考えのようだ

SQLTemplate

  • SQLTemplate(GUIだとRaw Query)で任意のSQLをDataAdapter毎に設定できる
  • SQLTemplateでは、射影が使用できるが、必ずPrimary keyはFETCHするようにしないといけない
  • 射影はMandatoryに設定した列は全てSELECTしないと、正しくobjectを作成できない。Mandatoryの列を全てSELECTしない状態で作成したEntityは、state:hollowになる

  • SQLは、Velocityでdynamicに変更できる
  • #bindで、prepareが実現出来る (User guideの7.7章を参照)
  • Raw SQL(GUI)のSQL文内で改行できるかどうかはJDBCドライバの実装による?(DB2=>OK,Derby=>NG)

  • SQLTemplateを使用して更新処理を行う場合は注意が必要。その更新はメモリ上のObjectStoreをバイパスして直接DBを操作するため、操作によってはObject GraphとDBで不整合を起こす可能性がある。(User Guide 7.6.3)

// 1.クエリをmap.xmlから取り出す
SelectQuery prototype=
 (SelectQuery)context.getEntityResolver()
 .lookupQuery("MySelect");

// 2. パラメタをセット
Map params = new HashMap();
params.put("aname", "Monet");
SelectQuery query = 
 prototype.queryWithParameters(params);

// 3. 実行
List objects = context.performQuery(query);

もしくは、(パラメタ設定なしの場合)
List objects = context.performQuery("MySelect", false);

ProcedureQuery


  • TBW

一つしか値を返さないクエリ


SingleObjectQueryクラスかDataObjectUtils.objectForQueryを使う。

See : SingleObjectQuery

並べ替え/ソート(Ordering)


query.addOrdering("artistName", true);
(ORDER BY ARTISTNAME ASC)
(第二引数をfalseにするとDESC)

  • 複数条件のOrderingもサポート
  • インメモリのソートはOrderingオブジェクトを使う(Orderingオブジェクト自体はインメモリだけのサポートではないかも)

Expression (WHEREのような絞込み)


Expression ObjectはExpression.fromString()で作成できる。
Expression e = Expression.fromString
 ("title like 'A%' and price < 1000");

以下の三種類のexpressionがある。

object property expressions (path expressions)


  • pathは、Beanのプロパティでも、DBの列名でも指定できる
  • pathはドット(.)で接続してリレーション先を指定できる

  • Path内での指定方法
単に文字列だとObject path -> artistName
obj:を付けると明示的にObject path -> obj:artistName
db:を付けると、database path -> db:ARTIST_NAME

  • path内での文字列リテラルはコーテーションで囲む必要有り
例 -> "'ABC'"  or "\"ABC\""

  • 文字列で直接Expressionを書く以外にも、ExpressionFactoryのmatchExp()などのファクトリメソッドで組み立てる方法もある。特にinExpは引数にListか配列が取れるので便利(User Guide 10.3)

arithmetic operations


conditional expressions


NULLの扱い

パラメタマーカ等にNULLがきても適切なSQLに変換される。
Expression.fromString("d = null");
ExpressionFactory.matchExp("d", null);
などとしても、WHERE D IS NULLに変換される。

In-memory evaluation

作成したExpressionは任意のJava Beanに適応できる(DataObjectを継承していなくても)
つまり、e.match(myObj)のmyObjは任意のJava Beanが使用できる。

FETCHの制限


SelectQuery#setFetchLimit(int fetchLimit)
Fetchの最大数を決める。SQLに修正が入るのではなく、単にFETCHする量を制限しているようだ

SelectQuery#setPageSize(int pageSize)
ページング(部分読み)の分割数の設定

クエリーしたオブジェクトのキャッシュ


NO_CACHE デフォルト。毎回DBにアクセス
LOCAL_CACHE 同一のDataContext内でキャッシュを使用
SHARED_CACHE 同一のJVM内でキャッシュを共有

  • JVM間をまたがるキャッシュは無いようだ

query.setName("MySelect");
query.setCachePolicy
 (GenericSelectQuery.LOCAL_CACHE);
query.setRefreshingObjects(false);

キャッシュの使用はクエリの名前で区別されるので、名前は重要。キャッシュポリシーはGUIでも設定可能

query.setRefreshingObjects(true/faluse);
デフォルトでは、true:リフレッシュする
リフレッシュもGUIで設定可能

DataContextとDataObject


  • DataObjectは、全てのEntityの基礎
  • DataContextにDataObjectを"Register"する事で、Entityの変更などがトラッキングされ、パーシステントされる
  • Registする方法は2つ
automatically when they are fetched via query API
Query APIで読み出したObjectは自動的にRegistされる。
つまりDataContext#PerformQuery()等で実行した場合、
FetchしたObjectは自動的にそのDataContextにRegistされる

explicitly for the newly created objects
新規に作成したObjectは、明示的にRegistしないといけない
context.registerNewObject(newObject); もしくは
context.createAndRegisterNewObject(*.class)を使う

DataObjectの状態

  • DataObjectは状態(State)を持つ。状態はDataObject.getPeristenceState()で確認できる

TRANSIENT newで作成されたが、Registされていない
NEW 作成され、RegistされたがDBにCommitされていない
COMMITTED DBにCommitされた
MODIFIED DBに存在するObjectでDataObject側が修正された。リレーション先が変更された場合も含む?
DELETED DataContext#deleteObject()されたDataObject
HOLLOW 不完全なオブジェクト?

  • DELETED状態のDataObjectは、commitChanges()でTRANSIENTな状態になる

  • DataContextにRegistされたObjectのうち一つでもNEW/MODIFIED/DELETEDになっているかどうかは、DataContext#hasChanges()で確認できる。

Validation


DataObjectが保持するデータが、RDBMSのスキーマにマッチするかどうかは、commitChanges()のタイミングで行われる。例えばCHAR(1)の列に対応したプロパティに"ABCDE"が設定されている場合DBにINSERTする前に Cayenne内でValidationが行われて、org.objectstyle.cayenne.validation.ValidationException が発生する。

Local Copy

  • sessionContext.localObjects(list)でローカルにコピーが作れる?(User guide 6.4)
  • listに含まれるObjectのStateはCOMMITEDかHOLLOWでなければいけない⇒READ ONLYデータ用
  • localObjectのStateは?

Primary key(PK)

基本的に、Cayenneにおけるプライマリーキーは、
  • Entityを識別するためのID
  • ビジネス上の意味を持たないのが望ましい(代理キー)
  • EntityはPKへのgetter/setterを持たないのが普通(modeler guideでもPKへのアクセッサをつけない事を推奨している)
  • PKの値はCayenneによって自動生成される
  • PKの値の生成には、DB2の場合はシーケンスが使用され(使用させない設定も可能)、START=200,Increment=20,Cache=20に設定される
  • CayenneのPKGeneratorクラス内でPKのシーケンスをあらかじめキャッシュしておいてそれを使う実装になっている(20個分)⇒つまりIDが20づつ増える訳ではなく、1づつ増える
  • Cache sizeはJdbcPkGenerator#setPkCacheSize(int)で設定で変更できる(だが1等に設定すると毎回DBMSにPKの問い合わせをする事になるのでパフォーマンスが低下する)
  • DB2の表側でID列を設定し、CayenneにPKを生成させないようにする方法もある(未テスト)

  • IDへのsetter/getterの作り方
http://www.atmarkit.co.jp/fjava/products/cayenne/cayenne_3.html
より引用

public Integer getId() {
    return (getObjectId() != null && !getObjectId().isTemporary()) ? 
(Integer)getObjectId().getIdSnapshot().get(ID_PK_COLUMN): null;
  }

public void setId(int id) {
  setObjectId(new ObjectId(Employee.class, "ID", id));
}

DataObjectからPKの値を取り出したり、PKの値(int)からDataObjectを取り出す場合は、DataObjectUtilsクラスを使用する事ができる。
しかしCayenneのデザインとしては、直接PKを操作するのは推奨されない。(DataObjectUtilsのJavaDocに書いてある)
(また、上記を手で実装するより、modelerで設定すれば良いのかも)

see also:
  • User Guide 4.7
  • ML 2003/01/0032
  • ML 2005/02/0034

トランザクション


  • DataContext.commitChanges()でCOMMIT(厳密には、このメソッドを読んだ時点で必要なSELECT,INSERT,UPDATE,DELETE文が自動的に作成され、実行され、COMMITされる。
  • DataContext.rollbackChanges()で、ROLLBACKというか、DataContextにRegistしているDataObjectの状態が元に戻される。この時、新規にNEWして手動でRegistしたDataObjectは、Registしていない状態に戻る

Cayenne Modeler (GUI)


  • GUIの設定は、C:\Documents and Settings\user\.cayenne\prefs\1.2以下に、HSQLDB形式で保存されている

  • GUIで定義したQueryは、new NamedQuery("Queryの名前")でQueryを作成する(もしくはDataContextのコンビニエンスメソッドperformQuery(String,boolean)を使用して直接実行する)

  • DB2の(VAR)GRAPHIC列は、2倍のサイズの(VAR)CHAR列 として読み込まれる。つまりVARGRAPHIC(10)は、VARCHAR(20)として扱われる。必要であればGUI上で手動修正が必要

  • DB上のTIMESTAMP型は、デフォルトではjava.util.Dateにマッピングされる。そのまま使っても良いが、不都合がある場合はGUI上でjava.sql.Timestampに変更する事もできる

Cayenneのメリット/強み


  • Modelerによるコード/XML/DDL自動生成
  • one to oneでもone to manyでもDataObject間で自動的に双方向リンクされる(他のORMでは難しいのでは?)
  • Remote persistence, good faulting implementation (と作者は言っている)

他フレームワークとのインテグレーション


  • Springとの連携例は、Cayenne exapmleにソースコードがある。
  • TapestryのISqueezeAdapterをCayenneに対応させたもの
  • Click Framework

メモ

  • キャッシュの動作が良く分からない
  1. setRefreshingObjects(true)にすると、キャッシュにデータが在っても必ずDBからFETCHするようだ
  2. setRefreshingObject(false)にすると、キャッシュにある場合、キャッシュから取り出して問題なく動作するがキャッシュに目的のDataObjectが無い場合でもSELECTを発行してくれないように見える
  3. Queryに付ける名前を同じにしないとキャッシュを共有できないようだ
  4. ある名前のQueryが最初に実行される時は、refreshing=falseでもFETCHされるようだ
  5. 、、、という事は、同じクエリを再度実行した時用のキャッシュという事??


  • Java EntityはJava Beanだが、(他のORMのように)プレインなBeanでは無く、Cayenneが用意したクラス(org.objectstyle.cayenne.CayenneDataObject)を継承している⇒プレゼンテーション層にデータを転送したい場合はDTOを作るなど一工夫があった方が良いかも

  • DataObjectを継承していない任意のPoJo BeansをPersistent可能にして欲しいというリクエストは以下にあるが、どう対応するかは決まっていないようだ(CAY-262)

  • EJB3のPersistence APIには対応する事は考えているようだ
http://objectstyle.org/confluence/display/CAY/2006/01/10/


  • どのDBに接続するかという情報をcayenne.xmlに記述したくない場合は、JNDI or Commons DBCPを使用して、そちらで変更する

  • Expressionで"deptno like 'x'"などと指定すると、生成されるSQLが
WHERE RTRIM(t0.DEPTNO) LIKE CAST (? AS VARCHAR(3))
とRTRIMやCASTが付加されたSQLとなる。

  • Optimistic Lock (楽観ロック)への対応
    • Optimistic Lockには対応している
    • 指定された列をすべて比較するタイプの実装
    • VERSION列(の自動更新)には対応していない
    • もし自動更新のVERSION列が欲しい場合は、自分でDataObject.setPersistenceState(..) をオーバーライドして実装するのが良いらしい
    • http://www.objectstyle.org/cayenne/lists/cayenne-user/2004/06/0060.html

リンク


  • Cayenne
  • Cayenne Wiki
  • Cayenne Examples on wiki
  • CayenneでORマッピング
  • 話題のO/Rマッピングツール「Cayenne」を使う
  • S2Cayenne

「Cayenne memo」をウィキ内検索
LINE
シェア
Tweet
Unofficial DB2 Wiki
記事メニュー
メニュー
  • トップページ
  • 更新履歴

■ DB2
├ Unofficial DB2 blog
├ DB2逆引きwiki
├ Unofficial DB2 FAQ
└ Cayenne memo

■ Derby関連
├ Derby memo
└ Derby Console
記事メニュー2

更新履歴

取得中です。
最近更新されたページ
  • 4116日前

    メニュー
  • 4116日前

    Derby memo
  • 6427日前

    Cayenne test
  • 6734日前

    Cayenne memo
  • 6912日前

    derbyconsole
  • 7118日前

    トップページ
  • 7129日前

    更新履歴
もっと見る
最近更新されたページ
  • 4116日前

    メニュー
  • 4116日前

    Derby memo
  • 6427日前

    Cayenne test
  • 6734日前

    Cayenne memo
  • 6912日前

    derbyconsole
  • 7118日前

    トップページ
  • 7129日前

    更新履歴
もっと見る
ウィキ募集バナー
新規Wikiランキング

最近作成されたWikiのアクセスランキングです。見るだけでなく加筆してみよう!

  1. MadTown GTA (Beta) まとめウィキ
  2. AviUtl2のWiki
  3. R.E.P.O. 日本語解説Wiki
  4. シュガードール情報まとめウィキ
  5. 機動戦士ガンダム EXTREME VS.2 INFINITEBOOST wiki
  6. ソードランページ @ 非公式wiki
  7. SYNDUALITY Echo of Ada 攻略 ウィキ
  8. シミュグラ2Wiki(Simulation Of Grand2)GTARP
  9. ドラゴンボール Sparking! ZERO 攻略Wiki
  10. 星飼いの詩@ ウィキ
もっと見る
人気Wikiランキング

atwikiでよく見られているWikiのランキングです。新しい情報を発見してみよう!

  1. アニヲタWiki(仮)
  2. ストグラ まとめ @ウィキ
  3. ゲームカタログ@Wiki ~名作からクソゲーまで~
  4. 初音ミク Wiki
  5. 検索してはいけない言葉 @ ウィキ
  6. 発車メロディーwiki
  7. Grand Theft Auto V(グランドセフトオート5)GTA5 & GTAオンライン 情報・攻略wiki
  8. 機動戦士ガンダム バトルオペレーション2攻略Wiki 3rd Season
  9. オレカバトル アプリ版 @ ウィキ
  10. モンスター烈伝オレカバトル2@wiki
もっと見る
全体ページランキング

最近アクセスの多かったページランキングです。話題のページを見に行こう!

  1. 参加者一覧 - ストグラ まとめ @ウィキ
  2. 魔獣トゲイラ - バトルロイヤルR+α ファンフィクション(二次創作など)総合wiki
  3. 高崎線 - 発車メロディーwiki
  4. 鬼レンチャン(レベル順) - 鬼レンチャンWiki
  5. 暦 未羽 - ストグラ まとめ @ウィキ
  6. 召喚 - PATAPON(パタポン) wiki
  7. ステージ攻略 - パタポン2 ドンチャカ♪@うぃき
  8. 暦 いのん - ストグラ まとめ @ウィキ
  9. 鬼太郎誕生 ゲゲゲの謎 - アニヲタWiki(仮)
  10. ロスサントス警察 - ストグラ まとめ @ウィキ
もっと見る

  • このWikiのTOPへ
  • 全ページ一覧
  • アットウィキTOP
  • 利用規約
  • プライバシーポリシー

2019 AtWiki, Inc.