Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome or Safari browser. Firefox 10 (to be released soon) will also handle it.

ゆるふわデータマッパーの話

@tsucchi

自己紹介

背景

データマッパー

Web アプリのDB層について(主にコンシューマ向け?)

業務系とか、業務系っぽい Web アプリのDB層について

良くある O/R Mapper を使ってて困ること

サンプル

CREATE TABLE person ( /* 人間 */
  id   INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT    NOT NULL,
);

CREATE TABLE detective ( /* 探偵 */
  id        INTEGER PRIMARY KEY AUTOINCREMENT,
  person_id INTEGER NOT NULL,
  toys      TEXT  NOT NULL,
  FOREIGN KEY(person_id) REFERENCES person(id)
);

CREATE TABLE police ( /* 警察 */
  id        INTEGER PRIMARY KEY AUTOINCREMENT,
  person_id INTEGER NOT NULL,
  iq        INTEGER,
  FOREIGN KEY(person_id) REFERENCES person(id)
);

テーブルとふつうにマッピングすると困ること(1)

my $row = $db->single('detective', { person_id => 100 });
$row->name; #これは無理(name は親テーブル person にあるから)

テーブルとふつうにマッピングすると困ること(2)

my $row = $db->create({ id => 100 }); # id=100が探偵さんだとして
$row->toys; #これができない(あるいはちょっとめんどい)

解決策

ゆるふわデータマッパー

やりかた

こんな感じ(1)

package Detective;
use Mouse;
extends 'Person';
...

こんな感じ(2)

こんな感じ(3)

package Person
use Mouse;
...
sub create {
    my ($class, $id) = @_;
    # 区分を親側で持っておいて、親の$row を子に渡して、
    # 子側で自分のテーブルを引く方が使いやすくてオススメではあります。下記のは説明用
    my $person_row = db->single('person', { id => $id });
    my $detective_row = db->single('detective', { person_id => $id });
    if ( defined $detective_row ) { #探偵が返る。name も引ける
        return Detective->create($person_row->name, $detective_row);
    }

    my $police_row = db->single('police', { person_id => $id });
    if ( defined $police_row ) { #警察が返る
        return Police->create($person_row->name, $police_row);
    }
    die "探偵でも警察でもないのはダメダメですー"
}

更新とか

結論

おしまい

Use a spacebar or arrow keys to navigate