オブジェクト関係マッピング

Ruby on RailsなどでDBを扱いやすくしてくれる、「オブジェクト関係マッピング」の概要をまとめた。

# オブジェクト関係マッピング（ORM）とは

[Wikipedia](http://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E9%96%A2%E4%BF%82%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0)より抜粋。
> オブジェクト関係マッピング（英: Object-relational mapping、O/RM、ORM）とは、
データベースとオブジェクト指向プログラミング言語の間の非互換なデータを変換するプログラミング技法である。
オブジェクト関連マッピングとも呼ぶ。実際には、オブジェクト指向言語から使える「仮想」オブジェクトデータベースを構築する手法である。
オブジェクト関係マッピングを行うソフトウェアパッケージは商用のものもフリーなものもあるが、場合によっては独自に開発することもある。

つまり、オブジェクト指向と関係データベースの考え方を上手く変換して繋いでくれるもの。

## ORMの役割

次項で説明する「インピーダンス・ミスマッチ」を解消して
関係データベース（RDB）のレコードを、オブジェクトとして直感的に扱えるようにする。
また、RDBにアクセスするプログラムを書く際の煩雑な処理を軽減させ、
プログラマはSQLを意識することなくプログラムを書ける。

## インピーダンス・ミスマッチ

オブジェクト指向は**「現実世界の物事に即したデータモデル」**である一方で、
関係データベースは**「検索やCRUDなどの処理に最適化されたデータモデル」**となっている。

このような設計思想の違いを、インピーダンス・ミスマッチという。

## 一般的なORMフレームワークでのマッピング処理

ORMにおける煩雑な処理は、すべてORMフレームワークが引き受ける。

1. クラスの属性とテーブルカラムの対応付けを、あらかじめ外部ファイル（XMLファイルなど）で定義しておく。
1. ORMフレームワークが属性とカラムのマッピングを処理する。
    * マッピング定義を記述したファイルから、スキーマやクラスのソースを自動生成する。
1. プログラマはORMフレームワークによって生成されたクラスと、提供されるAPIを用いてデータ操作を行う。

# ORMの例

## ActiveRecord （Ruby on Rails）

### 概要

Ruby on Railsに付属する、重要なライブラリの1つ。
名前は「Active Record」パターンに由来している。

ActiveRecordライブラリで、下記の仕組みが得られる。

* モデルとそのデータを表す仕組み
* モデル間の関連性を表す仕組み
* 関連するモデルを通した階層の継承を表す仕組み
* DBに保存する前に検証する仕組み
* オブジェクト指向の手法でDB操作を実行する仕組み

基本的に、1つのクラスがDBの1テーブルに対応している。

* クラスの属性は、テーブルの各カラムに対応。
* クラスの1インスタンス（オブジェクト）は、DBの1レコードに対応する。
* 各クラスは、ActiveRecord::Baseの派生クラスとして実装し、app/models下に格納する。

### マッピングのための命名規則

クラスとテーブルの対応には、名前に関する規約が利用される。

*      （例）テーブル名が books の場合、クラス名は Book
*     規約通りにクラスを作成すれば、中身が空でも正しくマッピングされる。
*     規約を外れる命令が必要な場合は、クラスに記述を追加すれば良い。

クラスの属性とカラムのマッピングも、設定を書かなくて良い。

*    ActiveRecordライブラリがDBのスキーマを実行時に読み取る。
*    カラム名と同じ名前の属性を使えるように、カラムのデータ型に従って属性が適切なRubyのクラスへ対応付けられる。

具体的な仕組みはlib/active_record下のソースを読むと良い（らしい）。

### 操作例

書籍を管理する下のようなbooksテーブルが存在し、Bookクラスと対応付けられている場合の操作例を示す。

| id | title | author_name |
|:--:|:--:|:--:|
| 1 | Book Title1 | Author1 |
| 2 | Book Title2 | Author2 |


**id = 1 のレコードを取り出す**

```
book = Book.find(1)
```

**取り出したレコードのtitleを表示**

```
book.title  # Book Title1
```

**取り出したレコードのauthor_nameを変更**

```
book.author_name = "New Author1"
book.save  # 保存される
```

**データを追加**

```
Book.create(title: "Book Title3", author_name: "Author3")
```

このように、SQL文を使わずにDB操作ができる。

## Core Data（Mac OS X、 iOS）

### 概要

Mac OS X、iOSで利用できる、Appleによって開発されたORMフレームワーク。

* データの永続化にSQLiteを使用している。
* 他にもXML、単純バイナリ形式をサポート。

永続化対象のデータをエンティティと呼ぶ。

Core Dataで、下記の機能が得られる。

* 変更の追跡、取り消し・再実行の処理
* オブジェクト間の関係の一貫性を含む、変更の影響範囲の管理
* オブジェクトの遅延読み込み機構によるプログラムのメモリ消費量削減
* プロパティ値の自動検証
* スキーマの移行
* 完全自動化されたキー値コーディングおよびキー値の監視
* データのグループ化、絞込み、組織化
* SQLを記述する代わりに複雑なクエリの生成
* 複数プロセスによる書き込みの衝突を自動解消する

関連クラスが多い。主要クラスは次の通り。

**NSManagedObject**
 
* モデルクラス。
* Core Dataで永続化するオブジェクトは、必ずこのクラスか、このクラスのサブクラスのオブジェクトでなければいけない。
    
**NSManagedObjectContext**

* データの検索、CRUDを行うクラス。

**NSFetchRequest**

* 検索条件を管理する。
* ここで指定した条件がSQLに変換されて検索に使われる。

**NSFetchedResultsController**

* オブジェクトを監視するコントローラクラス。
* オブジェクトのCRUD時に通知する。

**NSEntityDescription**

* エンティティ（データ）の定義を管理する。

**NSManagedObjectModel**

* エンティティ（データ）同士の関連を管理する。

**NSPersistentStore**

* DBの情報を管理する。

## その他

**Java**

* [ICIQL](http://iciql.com/)
* [Hibernate](http://hibernate.org/)
* [S2JDBC](http://s2container.seasar.org/2.4/ja/s2jdbc.html)
* [Doma](http://doma.seasar.org/)
* [S2Dao](http://s2dao.seasar.org/ja/)
* [ActiveObjects](https://developer.atlassian.com/docs/atlassian-platform-common-components/active-objects)

**PHP**

* [Doctrine](http://www.doctrine-project.org/)
* [Propel](http://propelorm.org/)
* [PHPDAO](http://phpdao.sourceforge.net/)
* [php activerecord](http://www.phpactiverecord.org/)
* [idiorm](http://j4mie.github.io/idiormandparis/)

**Ruby**

* [TapKit](http://www.spice-of-life.net/tapkit/index_ja.html)
* [Sequel](http://sequel.jeremyevans.net/)

**Android**

* [OrmLite](http://ormlite.com/)
* [ORMAN](https://github.com/ahmetalpbalkan/orman)
* [ActiveAndroid](http://www.activeandroid.com/)

# 参考にさせていただいたサイト

* [オブジェクト関係マッピング - Wikipedia](http://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E9%96%A2%E4%BF%82%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0)
* [Hibernateで理解するO/Rマッピング（1）：O/Rマッピングの役割とメリット - ＠IT](http://www.atmarkit.co.jp/ait/articles/0404/13/news075.html)
* [Activeレコードの基本 | Rails日本語ドキュメント | Ruby STUDIO](http://ruby.studio-kingdom.com/rails/guides/active_record_basics)
* [Active Record - Wikipedia](http://ja.wikipedia.org/wiki/Active_Record)
* [Ruby on Rails3で学ぶWeb開発のキホン（3）：「ActiveRecord」の基本とデータの参照 (1/2) - ＠IT](http://www.atmarkit.co.jp/ait/articles/1104/12/news135.html)
* [O/R Mapping の話をするよ。ActiveRecord の話をしたかった。](http://www.slideshare.net/TomohikoHimura/or-mapping-activerecord)
* [サルでもわかる Core Data 入門【概念編】 - A Day In The Life](http://d.hatena.ne.jp/glass-_-onion/20111015/1318667971)
* [Core Dataプログラミングガイド (TP40001075 0.0.0) - CoreData.pdf](https://developer.apple.com/jp/devcenter/ios/library/documentation/CoreData.pdf)