開発を支える技術 ~ORMフレームワーク編~

# ORM(Object-Relational Mapping)とは?
下手な説明をするよりも、[Wikipedia](https://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）とは、データベースとオブジェクト指向プログラミング言語の間の非互換なデータを変換するプログラミング技法である。オブジェクト関連マッピングとも呼ぶ。

具体的に言うと、オブジェクト指向プログラミング言語(Java,C#...)における<font color="red">**オブジェクト**</font>と関係データベース(Olacle,MySQL...)における<font color="red">**レコード**</font>を「対応づける(Mapping)」プログラミング技法のことです。

***

# ORMをなぜ使うのか?
オブジェクト指向プログラミング(以下,OOP:Object-oriented programming)と関係データベース(以下,RDB:Relational database)、これら2つがもつそれぞれのデータモデルに違いによって生じる、<font color="red">**インピーダンスミスマッチ**</font>を解消するためです。

***

# インピーダンスミスマッチって何?
[インピーダンスミスマッチ(impedance mismatch)](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%83%94%E3%83%BC%E3%83%80%E3%83%B3%E3%82%B9%E3%83%9F%E3%82%B9%E3%83%9E%E3%83%83%E3%83%81)は元々、電気工学の用語で「抵抗の不整合」とか「抵抗の不一致」的な意味合いです。
ものすごく大まかに説明すると、「電気抵抗の異なる2つの素材に対して、電磁波を通そうとすると電気的なエネルギーが効率良く伝搬できない。」という事象のことを指しています。

![mismatch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198150/64dfff23-2ee3-3ed5-ee79-5fe2c02f8d83.png)

これだけ説明すると、OOPとRDBに何が関係あるんだ？
と思われるかも知れませんが、確かにインピーダンスミスマッチの詳細自体はあんまり関係がありません...
ただ、物事の詳細を知っておくと「例え」を与えられたときに分かりやすいので説明してみました。

実際に上記の「[ORMをなぜ使うのか?](# ORMをなぜ使うのか?)」で使われている「インピーダンスミスマッチ」は比喩表現で、<font color="red">**コンセプトの違う2つの分野・領域を繋ごうとする時に発生する困難や不都合**</font>のことをさしています。

***

特にOOPとRDBの間で発生するもの関しては、<font color="red">**O/R インピーダンスミスマッチ**</font>と言われています。

#### [OOPの特徴]
- オブジェクトは階層的な構造をもっており、考え方が3次元的(抽象クラスやインターフェースを使った継承)

#### [RDBの特徴]
- RDBは項を中心として2次元の「表」で表現されることが多い


![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198150/a672fdec-c48e-813b-be03-1903fbd77fb8.jpeg)


OOPで各テーブル同士のリレーションシップを表現しようとした際などに**O/R インピーダンスミスマッチ**が発生する。

***

# ORMってどうやって使うの?
最初に説明した通り、**ORMはプログラミング手法の1つです。**
ORMということ言葉を知っているだけでは、O/R インピーダンスミスマッチは解決されません。
実際のプログラミングに反映させる必要があります。それを実現してくれる仕組みを<font color="red">**O/Rマッパー、ORMフレームワーク**</font>と呼びます。
OOPをコンセプトとする多くの言語にO/Rマッパーは存在します。
ここでは詳しい説明は省かせていただきますが、ざっとどんなものがあるのかだけはご紹介します。

#### C-sharp
- [Entity Framework](https://docs.microsoft.com/en-us/ef/)
- [Dapper](https://github.com/StackExchange/Dapper)

#### Java
- [S2JDBC](http://s2container.seasar.org/2.4/ja/s2jdbc.html)

#### Golang
- [gorm](https://github.com/jinzhu/gorm)

#### Ruby
- [ActiveRecord](https://guides.rubyonrails.org/active_record_basics.html)

***

# O/Rマッパーを使うとSQLを書かなくて済む?
> O/Rマッパーを使えば、SQLを書かなくていいから学習コストが低い！

とか

> O/RマッパーはSQLを書きたくない人のためのツールだ！

という言葉を聞いたことがあるでしょうか?
確かにO/Rマッパーを使えば、SQLを書かなくて済む場面はたくさんあります。
しかし、ここで忘れないで欲しいのは、<font color="red">**「SQLを書きたくない人のためのツール」としてO/Rマッパーは誕生したわけではないということです。**</font>

O/Rインピーダンスミスマッチを解決するため、方法の一つの形(プログラミング技法)としてO/Rマッパーがそういった状態を提供しているにすぎません。
そして、もう一つ忘れてはいけないのは、<font color="red">**結局のところDBのアクセスにはSQLが使われているという事実です。**</font>

***

# O/Rマッパーを使っても学習コストからは逃げられない

```csharp

// O/Rマッパーを返したこのDBへのアクセスでどんなSQLが発行されているかわかりますか?
// これで発行されたSQLが思ったもの違った場合、どうやって目的のSQLを発行させるかわかりますか?
using (var ctnx = new DbContext(connectionString))
{
  var result = ctnx.USER.Where(u => u.id == 1 && u.name == "test").FirstOrDefault();
}

```
性能面で問題が発生すると、SQLからは逃れられません。

- どんなQueryが発行されているのか?
- どんなQueryを発行するべきなのか?
- O/Rマッパーではそれをどうやって表現するのか?

むしろ「SQLを直接発行する」という選択肢を取っていれば、<font color="red">**SQLの学習コストだけで済んでいたかも知れません。**</font>
O/Rマッパーで目的とするQueryを発行するためには、O/Rマッパーの使用法とSQLの両方を覚える必要が...

***


# まとめ
#### :one: ORMはOOPのオブジェクトとRDBのレコードを対応付けするプログラミング技法
#### :two: ORMを実現するためにO/RマッパーやORMフレームワークを使う。
#### :three: O/Rマッパーは「SQLを書きたくない人のためのツール」ではない。

***

# 参考・引用
- [O/Rマッピングは百害あって一利なし！](https://qiita.com/gomiryo/items/6d448c500749f91242d2)
- [O/Rマッピングツールに対する誤解をときたい](https://blog.jnito.com/entry/20100528/1274998429)
- [SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か？ - SlideShare](https://www.slideshare.net/kwatch/sqlor)
- [[雑記] O/R インピーダンスミスマッチ](https://ufcpp.net/study/csharp/sp3_ormismatch.html)