Pattern of Enterprise
Application Architecture
Chapter 3
リレーショナルデータベースへのマッピング

WRWR at Csus4.net
http://www.csus4.net/d/日本語版 目次
• アーキテクチャに関するパターン : P035
• 振る舞いに関する問題 : P040
• データの読み込み : P042
• 構造的なマッピングに関するパターン : P043
– 関係のマッピング : P043
– 継承 : P047

• マッピングの構築 : P050
– 2重のマッピング : P051

• メタデータの使用 : P052
• データベース接続 : P053
• その他の要点 : P055
• 参考文献 : P056
2005/05/22

PofEAA Chap32

3.1 アーキテクチャに関するパターン• ゲートウェイ/DAOによるレイヤ化• ゲートウェイの構成と分類• ドメインロジック/ビジネスロジックとの関係• ビューとクエリー• ドメインモデルの永続化

2005/05/22

PofEAA Chap33

ゲートウェイ/DAOによるレイヤ化
P187-188. T he Case of the Missing Element

ビジネスロジック

ゲートウェイ/DAO

SQL

User
PK
1
2

name
foo
bar

deptId1001
1002

データアクセスレイヤの導入• メリット– SQLの隠蔽/分離 （プログラム・プログラマ）– データアクセスレイヤへのSQLアクセス処
理の一元化
2005/05/22

PofEAA Chap3

4

ゲートウェイの構成と分類• 行データゲートウェイ– RDBレコード1つに1インスタンス– オブジェクト指向の考え方に適合• テーブルデータゲートウェイ– RDBテーブル1つに1インスタンス– レコードセットに適合

2005/05/22

PofEAA Chap3

5行データゲートウェイの概念
insertupdatedelete
User
PK
1
2

name
foo
bar

deptId1001
1002

インスタンスとレコードの対応

2005/05/22

PofEAA Chap3

6行データゲートウェイのバリエーション
PersonFinder
find(id)findForCompany(companyID)PersonGateway
lastnamefirstnamenumberOfDependents

PersonGateway

insertupdatedeletefind(id)findForCompany(companyID)

lastnamefirstnamenumberOfDependents
insertupdatedelete

図3.1 (P36)2005/05/22

10.2章 (P162)
PofEAA Chap3

7

テーブルデータゲートウェイの概念
find(...)
RecordSet
User
PK
1
2

name
foo
bar

deptId1001
1002

insert(id, ...)
update(id, ...)
delete(id)2005/05/22

User

Gateway

PofEAA Chap3

PK
1
2

name
foo
bar

deptId
1001
1002

3

baz

1003

8

テーブルデータゲートウェイ

PersonGateway

Find(id) : RecordSet
findWithLastName(String) : RecordSetUpdate(id, lastName, firstName, numberOfDependencies)
Insert(lastName, firstName, numberOfDependencies)
Delete(id)

図3.2 (P36)2005/05/22

PofEAA Chap39

ドメインロジックとゲートウェイ• テーブルモジュール–

テーブルデータゲートウェイ• ドメインモデル– ロジックがシンプルかつ、テーブルとオブジェクトの関係がシンプル
アクティブレコード– ロジックが複雑かつ、テーブルのオブジェクトの関係が複雑
データマッパー• 多種のゲートウェイを併用してよい– しかし、混乱を招く恐れあり– 併用せざるを得ないケースもある
2005/05/22

PofEAA Chap3

10アクティブレコード
PersonlastnamefirstnamenumberOfDependents
insertupdatedelete

データアクセスをカプセル化
getExemption
isFlaggedForAudit
getTaxableEarnings

ビジネスロジックを配置
2005/05/22

PofEAA Chap311

データマッパー

PersonlastnamefirstnamenumberOfDependents
getExemption
isFlaggedForAudit
getTaxableEarnings

2005/05/22

PersonMapper
insertupdatedeletePofEAA Chap312

ドメインモデルの永続化• OODBの利用– 最もシンプルなドメインモデルの永続化方法– 長所• 生産性の向上

– 短所
• リスク

• O-Rマッピングツールの利用

2005/05/22

PofEAA Chap3

13

3.2 振る舞いに関する問題• 読み込みと保存に関する• ユニットオブワーク• 一意マッピング• レイジーロード

2005/05/22

PofEAA Chap314

ユニットオブワークの概念
New!

オブジェクトの読み込みと更新を記録する
UnitOfWork

2005/05/22

registerNew(obj)registerDirty(obj)registerClean(obj)registerDeleted(obj)commit()PofEAA Chap315一意マッピングの概念

同一レコードに対して2つのオブジェク
トが存在すべきでない

2005/05/22

User
PK12

PofEAA Chap3

namefoobardeptId
10011002

16

レイジーロードの概念1)

2)

アクセスfire!
fetch3)load

2005/05/22

PofEAA Chap3

17データの読み込み• findメソッド– 実装方法• staticメソッドとして実装する• Finderクラスを設ける• 読み込みの効率化– 経験則• 1度に複数行を取得するほうが良い• ジョインを使用するほうが良い– 実際問題・・・• DBAに相談せよ• プロファイルを取得せよ
2005/05/22

PofEAA Chap3

18

3.3 構造的なマッピングに関するパターン• 関係のマッピング– 一意フィールド
– 外部キーマッピング– 関連テーブルマッピング– 順序を持ったコレクション– バリューオブジェクト– シリアライズLOBとXML• 継承

2005/05/22

PofEAA Chap319一意フィールド

PersonPersonid : longPK
12• テーブルのキーをオブジェクトのフィールドにマッピングする
2005/05/22

PofEAA Chap3

20

外部キーマッピング
User

Dept

name: String1*

name: String

User
PK
12

2005/05/22

namefoobar

Dept
deptId1001
1002

deptId1001
1002

PofEAA Chap3

namefoobar21

関連テーブルマッピング
Employee
name: String

Skill
*
*

Employees

skill - employeesID
12empID12

2005/05/22

skillID
1001
1002

PofEAA Chap3

name: StringSkills
ID
1001
1002

name
foobar22

順序を持ったコレクション• 順序を持ったコレクション– OO言語では一般的かつ有用– RDBでは取り扱いが難しい–
順序を持たないコレクションに利用を検討すべき–もしくは、常にあるソート順でデータを取得するようにする

2005/05/22

PofEAA Chap323

参照整合性• 参照整合性が更新の邪魔になるケースがある• 参照整合性に引っかからないように更新処理を実行する方法– 整合性チェックをコミット時まで遅延させる– 更新のトポロジカルソートを行う

2005/05/22

PofEAA Chap324

バリューオブジェクト<<value>>
Money

EmployeesalaryID
name: String

amount: decimal
currency: char

Employees
ID
1
2

name

salaryAmount salaryCurrency

Money

EmployeesPK122005/05/22

name moneyID
1001
1002

moneyID
1001
PofEAA Chap3 1002

amountcurrency25

シリアライズLOB/XML• 利点– 階層的データ構造を自然に格納できる• 欠点– クエリのインタフェースがポータブルでない• XPathの普及に期待！

• 結論– 検索不要な、独立性が高い部分に使用するが吉2005/05/22

PofEAA Chap326

継承• シングルテーブル継承• 具象テーブル継承• クラステーブル継承

2005/05/22

PofEAA Chap3

27

シングルテーブル継承• 親Entityと子Entityを単一のテーブルに格納する• スペースを食う• パフォーマンス良い• 継承されたアトリビュー
トは複製されない• サブクラス（やスーパークラス）の識別に”type”を用いる
2005/05/22

PersonEmployee Customer

Person共通
属性

PofEAA Chap3

idpersonTypenamebirthday
cur_ordersalary28

具象テーブル継承• 継承アトリビュートを含め、すべての属性が複製される

共通属性
2005/05/22

PofEAA Chap3

PersonEmployeeCustomer

EmployeeCustomerid
namebirthdaysalaryid
namebirthdaypayment29

クラステーブル継承
Person• 継承ツリー間で属性が共有されない
共通属性

id
namebirthday

Person2005/05/22

PofEAA Chap3

Employee

Customer

Employee

Customer

idsalaryid
cur_order30

多重継承への対処• WR:よくわかりません・・・

2005/05/22

PofEAA Chap3

31

3.4 マッピングの構築• 3つの状況– スキーマを自分で選択する。
– 変更できない既存のスキーマへのマッピングを行わなくてはならない。
– 既存のスキーマへのマッピングを行わなければいけないが、このための変更には交渉の余地がある。

2005/05/22

PofEAA Chap332

2重のマッピング

Gateway

PersonA
PK
12

PersonPK
12

仮想的なデータソース

Gateway

PersonB
PK12

似たようなテーブルが存在
2005/05/22

PofEAA Chap333

3.5 メタデータマッピング
構造のマッピング
PersonPK12

Person

メタデータクエリのマッピング?

SQL

クエリオブジェクト
2005/05/22

PofEAA Chap3

34

3.6 データベース接続• データベース接続とレコードセット• データベース接続とコネクションプール
• 接続の管理2005/05/22

PofEAA Chap335

データベース接続とレコードセット• 切断されたレコードセット– 接続を閉じた後に処理される– ex. ADO.netの非接続型DataSet• 接続されたレコードセット– 処理される間、接続を維持する必要あり– ex. ???

2005/05/22

PofEAA Chap3

36

データベース接続とコネクションプール
• コネクションプールすべき（一般に）– 多くのプラットフォームではプールが提供される• プールのインタフェース– 適切にカプセル化されている場合が多い
オープン
プールからの取得

クローズ
プールへの解放• トランザクションとプール– 特定のトランザクションには同一の接続を割り当てる必要がある
2005/05/22

PofEAA Chap337接続の割り当て法(1)doHoge(con, param, ...)

doFuga(con, param, ...)

• 明示的な引数に接続を指定する。
– コネクションを引き回す格好となる

2005/05/22

PofEAA Chap338

接続の割り当て法(2)doHoge(param, ...)

doFuga(param, ...)

スレッドスコープのレジストリ
2005/05/22

PofEAA Chap339

接続のクローズ管理• 方法2つ– ガベージコレクションと関連付ける
•

推奨しない

– トランザクションと関連付ける• 機能との結びつきがわかりやすく、管理しやすい– ユニットオブワーク•

2005/05/22

推奨できる

PofEAA Chap340

おわり

2005/05/22

PofEAA Chap341