DBIx::Skinny - simple OR mapper
YAPC::Asia 2009
2009-09-10
自己紹介
continued...
Skinnyってなに?
continued...
Skinnyってなに?
- SQLベースのSimple ORM
- DBICの不満を解消すべくスクラッチでかいた自作ORM
なんで作ったか
continued...
なんで作ったか
- DBIC便利なんだけど、
- 柔軟て?
- DBICで発行されるSQLが微妙
- パフォーマンスを考慮したSQLが発行される訳ではない
continued...
なんで作ったか
- DBIC便利なんだけど、
- 柔軟て?
- DBICで発行されるSQLが微妙
- パフォーマンスを考慮したSQLが発行される訳ではない
- そもそもORMにパフォーマンスを考慮したSQLを求めるべきではない希ガス
continued...
なんで作ったか
- DBIC便利なんだけど、
- 柔軟て?
- DBICで発行されるSQLが微妙
- パフォーマンスを考慮したSQLが発行される訳ではない
- そもそもORMにパフォーマンスを考慮したSQLを求めるべきではない希ガス
- それぞれのDB構成によってチューニングの仕方かわってくる(インデックスとか正規化とか
continued...
なんで作ったか
- DBIC便利なんだけど、
- 柔軟て?
- DBICで発行されるSQLが微妙
- パフォーマンスを考慮したSQLが発行される訳ではない
- そもそもORMにパフォーマンスを考慮したSQLを求めるべきではない希ガス
- それぞれのDB構成によってチューニングの仕方かわってくる(インデックスとか正規化とか
- 会社によってはSQLプロフェッショナルがいるんじゃないかしら
continued...
なんで作ったか
- DBIC便利なんだけど、
- 柔軟て?
- DBICで発行されるSQLが微妙
- パフォーマンスを考慮したSQLが発行される訳ではない
- そもそもORMにパフォーマンスを考慮したSQLを求めるべきではない希ガス
- それぞれのDB構成によってチューニングの仕方かわってくる(インデックスとか正規化とか
- 会社によってはSQLプロフェッショナルがいるんじゃないかしら
- ORMはデータとオブジェクトの架け橋であるだけでよし
DBICの問題点
continued...
DBICの問題点
- DBICでは複雑なPerlのデータ構造をもとに複雑なSQLは組み立て可能
continued...
DBICの問題点
- DBICでは複雑なPerlのデータ構造をもとに複雑なSQLは組み立て可能
continued...
DBICの問題点
- DBICでは複雑なPerlのデータ構造をもとに複雑なSQLは組み立て可能
- これはいい部分でもあるが、
- DBICで生成したSQLを実行させるとパフォーマンスがでない事が多い
continued...
DBICの問題点
- DBICでは複雑なPerlのデータ構造をもとに複雑なSQLは組み立て可能
- これはいい部分でもあるが、
- DBICで生成したSQLを実行させるとパフォーマンスがでない事が多い
- 結局複雑なSQLは直接DBIを叩く事が多い
continued...
DBICの問題点
- DBICでは複雑なPerlのデータ構造をもとに複雑なSQLは組み立て可能
- これはいい部分でもあるが、
- DBICで生成したSQLを実行させるとパフォーマンスがでない事が多い
- 結局複雑なSQLは直接DBIを叩く事が多い
- しかしDBIを直接叩いた場合
continued...
DBICの問題点
- DBICでは複雑なPerlのデータ構造をもとに複雑なSQLは組み立て可能
- これはいい部分でもあるが、
- DBICで生成したSQLを実行させるとパフォーマンスがでない事が多い
- 結局複雑なSQLは直接DBIを叩く事が多い
- しかしDBIを直接叩いた場合
continued...
DBICの問題点
- DBICでは複雑なPerlのデータ構造をもとに複雑なSQLは組み立て可能
- これはいい部分でもあるが、
- DBICで生成したSQLを実行させるとパフォーマンスがでない事が多い
- 結局複雑なSQLは直接DBIを叩く事が多い
- しかしDBIを直接叩いた場合
- inflateしてくれない
- utf8flag周りの処理をしてくれない etc...
continued...
DBICの問題点
- DBICでは複雑なPerlのデータ構造をもとに複雑なSQLは組み立て可能
- これはいい部分でもあるが、
- DBICで生成したSQLを実行させるとパフォーマンスがでない事が多い
- 結局複雑なSQLは直接DBIを叩く事が多い
- しかしDBIを直接叩いた場合
- inflateしてくれない
- utf8flag周りの処理をしてくれない etc...
- DBICに設定した色々な便利機能が有効じゃない
continued...
DBICの問題点
- DBICでは複雑なPerlのデータ構造をもとに複雑なSQLは組み立て可能
- これはいい部分でもあるが、
- DBICで生成したSQLを実行させるとパフォーマンスがでない事が多い
- 結局複雑なSQLは直接DBIを叩く事が多い
- しかしDBIを直接叩いた場合
- inflateしてくれない
- utf8flag周りの処理をしてくれない etc...
- DBICに設定した色々な便利機能が有効じゃない
- 設定はDBICに持たせているがそれを旨く使えないか?
continued...
DBICの問題点
- DBICでは複雑なPerlのデータ構造をもとに複雑なSQLは組み立て可能
- これはいい部分でもあるが、
- DBICで生成したSQLを実行させるとパフォーマンスがでない事が多い
- 結局複雑なSQLは直接DBIを叩く事が多い
- しかしDBIを直接叩いた場合
- inflateしてくれない
- utf8flag周りの処理をしてくれない etc...
- DBICに設定した色々な便利機能が有効じゃない
- 設定はDBICに持たせているがそれを旨く使えないか?
- DBICのソースコードははっきり言って読むのが大変
continued...
DBICの問題点
- DBICでは複雑なPerlのデータ構造をもとに複雑なSQLは組み立て可能
- これはいい部分でもあるが、
- DBICで生成したSQLを実行させるとパフォーマンスがでない事が多い
- 結局複雑なSQLは直接DBIを叩く事が多い
- しかしDBIを直接叩いた場合
- inflateしてくれない
- utf8flag周りの処理をしてくれない etc...
- DBICに設定した色々な便利機能が有効じゃない
- 設定はDBICに持たせているがそれを旨く使えないか?
- DBICのソースコードははっきり言って読むのが大変
- つまり拡張が大変
DBICの問題点(つづき
continued...
DBICの問題点(つづき
continued...
DBICの問題点(つづき
- 重い
- 1つのオブジェクトが大量のオブジェクトで構成されている
continued...
DBICの問題点(つづき
- 重い
- 1つのオブジェクトが大量のオブジェクトで構成されている
- オブジェクト生成のコストもでかい
continued...
DBICの問題点(つづき
- 重い
- 1つのオブジェクトが大量のオブジェクトで構成されている
- オブジェクト生成のコストもでかい
- パフォーマンスに問題が無いクエリを実行してても
continued...
DBICの問題点(つづき
- 重い
- 1つのオブジェクトが大量のオブジェクトで構成されている
- オブジェクト生成のコストもでかい
- パフォーマンスに問題が無いクエリを実行してても
- オブジェクト生成に時間がかかるため、HotSpotではDBICをはずすことも
continued...
DBICの問題点(つづき
- 重い
- 1つのオブジェクトが大量のオブジェクトで構成されている
- オブジェクト生成のコストもでかい
- パフォーマンスに問題が無いクエリを実行してても
- オブジェクト生成に時間がかかるため、HotSpotではDBICをはずすことも
- デバッグしにくい
continued...
DBICの問題点(つづき
- 重い
- 1つのオブジェクトが大量のオブジェクトで構成されている
- オブジェクト生成のコストもでかい
- パフォーマンスに問題が無いクエリを実行してても
- オブジェクト生成に時間がかかるため、HotSpotではDBICをはずすことも
- デバッグしにくい
- DBICのオブジェクトをDumpするとほんとにありがとうございました
DBICの素晴らしい部分
continued...
DBICの素晴らしい部分
continued...
DBICの素晴らしい部分
- 色々文句もありますが
- なれれば簡単に色々な事ができるので開発効率がかなりあがる
continued...
DBICの素晴らしい部分
- 色々文句もありますが
- なれれば簡単に色々な事ができるので開発効率がかなりあがる
- 実際DBIだけで開発するより圧倒的な効率化がはかれる
continued...
DBICの素晴らしい部分
- 色々文句もありますが
- なれれば簡単に色々な事ができるので開発効率がかなりあがる
- 実際DBIだけで開発するより圧倒的な効率化がはかれる
- resultsetをつかったインクリメンタルなsearchがかなり便利
continued...
DBICの素晴らしい部分
- 色々文句もありますが
- なれれば簡単に色々な事ができるので開発効率がかなりあがる
- 実際DBIだけで開発するより圧倒的な効率化がはかれる
- resultsetをつかったインクリメンタルなsearchがかなり便利
- 機能が豊富
continued...
DBICの素晴らしい部分
- 色々文句もありますが
- なれれば簡単に色々な事ができるので開発効率がかなりあがる
- 実際DBIだけで開発するより圧倒的な効率化がはかれる
- resultsetをつかったインクリメンタルなsearchがかなり便利
- 機能が豊富
continued...
DBICの素晴らしい部分
- 色々文句もありますが
- なれれば簡単に色々な事ができるので開発効率がかなりあがる
- 実際DBIだけで開発するより圧倒的な効率化がはかれる
- resultsetをつかったインクリメンタルなsearchがかなり便利
- 機能が豊富
- 世界的に有名なPerlHackerによってメンテナンスされているので安心感がある
continued...
DBICの素晴らしい部分
- 色々文句もありますが
- なれれば簡単に色々な事ができるので開発効率がかなりあがる
- 実際DBIだけで開発するより圧倒的な効率化がはかれる
- resultsetをつかったインクリメンタルなsearchがかなり便利
- 機能が豊富
- 世界的に有名なPerlHackerによってメンテナンスされているので安心感がある
- 逆に開発スピードが早すぎて、置いてかれる可能性もあるけど
continued...
DBICの素晴らしい部分
- 色々文句もありますが
- なれれば簡単に色々な事ができるので開発効率がかなりあがる
- 実際DBIだけで開発するより圧倒的な効率化がはかれる
- resultsetをつかったインクリメンタルなsearchがかなり便利
- 機能が豊富
- 世界的に有名なPerlHackerによってメンテナンスされているので安心感がある
- 逆に開発スピードが早すぎて、置いてかれる可能性もあるけど
- 他のORMに比べるとノウハウも豊富に溜まってきた
ただ....
continued...
ただ....
- 不満の部分がいかんともしがたかった
- よくよく周りと話をすると、同じ事で不満に思っている人が多かった
continued...
ただ....
- 不満の部分がいかんともしがたかった
- よくよく周りと話をすると、同じ事で不満に思っている人が多かった
- DBIC以外でもData::ModelとかDODとかFeyとかDBIx::MoCoとかある
continued...
ただ....
- 不満の部分がいかんともしがたかった
- よくよく周りと話をすると、同じ事で不満に思っている人が多かった
- DBIC以外でもData::ModelとかDODとかFeyとかDBIx::MoCoとかある
- あるけど、生のSQLをいい感じにやってくれるのがなかった
そしてSkinnyへ
continued...
そしてSkinnyへ
- 仕事/プライベートの開発でずっとDBICをつかってきた
continued...
そしてSkinnyへ
- 仕事/プライベートの開発でずっとDBICをつかってきた
- そこで不満が
continued...
そしてSkinnyへ
- 仕事/プライベートの開発でずっとDBICをつかってきた
- そこで不満が
continued...
そしてSkinnyへ
- 仕事/プライベートの開発でずっとDBICをつかってきた
- そこで不満が
continued...
そしてSkinnyへ
- 仕事/プライベートの開発でずっとDBICをつかってきた
- そこで不満が
- 仕事場
- 生SQLつかいたいところで、だるい
- オブジェクトがでかくてだるい
continued...
そしてSkinnyへ
- 仕事/プライベートの開発でずっとDBICをつかってきた
- そこで不満が
- 仕事場
- 生SQLつかいたいところで、だるい
- オブジェクトがでかくてだるい
- 速度がでなくてだるい
continued...
そしてSkinnyへ
- 仕事/プライベートの開発でずっとDBICをつかってきた
- そこで不満が
- 仕事場
- 生SQLつかいたいところで、だるい
- オブジェクトがでかくてだるい
- 速度がでなくてだるい
- プライベート
continued...
そしてSkinnyへ
- 仕事/プライベートの開発でずっとDBICをつかってきた
- そこで不満が
- 仕事場
- 生SQLつかいたいところで、だるい
- オブジェクトがでかくてだるい
- 速度がでなくてだるい
- プライベート
continued...
そしてSkinnyへ
- 仕事/プライベートの開発でずっとDBICをつかってきた
- そこで不満が
- 仕事場
- 生SQLつかいたいところで、だるい
- オブジェクトがでかくてだるい
- 速度がでなくてだるい
- プライベート
- ライブラリがでかい
- しょぼいVPSだから重いのやだ
continued...
そしてSkinnyへ
- 仕事/プライベートの開発でずっとDBICをつかってきた
- そこで不満が
- 仕事場
- 生SQLつかいたいところで、だるい
- オブジェクトがでかくてだるい
- 速度がでなくてだるい
- プライベート
- ライブラリがでかい
- しょぼいVPSだから重いのやだ
- DBIC便利だけどもっと軽量&生SQLをいい感じに扱えるものが欲しい
continued...
そしてSkinnyへ
- 仕事/プライベートの開発でずっとDBICをつかってきた
- そこで不満が
- 仕事場
- 生SQLつかいたいところで、だるい
- オブジェクトがでかくてだるい
- 速度がでなくてだるい
- プライベート
- ライブラリがでかい
- しょぼいVPSだから重いのやだ
- DBIC便利だけどもっと軽量&生SQLをいい感じに扱えるものが欲しい
- じゃあつくろう
前提
continued...
前提
- 普段はスピード感をだせる開発をしつつ
- HotSpotな部分でDBIのような柔軟性効率化をはかりつつ
continued...
前提
- 普段はスピード感をだせる開発をしつつ
- HotSpotな部分でDBIのような柔軟性効率化をはかりつつ
- そういう時でも便利機能は提供しつつ
continued...
前提
- 普段はスピード感をだせる開発をしつつ
- HotSpotな部分でDBIのような柔軟性効率化をはかりつつ
- そういう時でも便利機能は提供しつつ
- シンプル構成なものが欲しい
continued...
前提
- 普段はスピード感をだせる開発をしつつ
- HotSpotな部分でDBIのような柔軟性効率化をはかりつつ
- そういう時でも便利機能は提供しつつ
- シンプル構成なものが欲しい
- もともとORMが作るSQLに多くを求めない
continued...
前提
- 普段はスピード感をだせる開発をしつつ
- HotSpotな部分でDBIのような柔軟性効率化をはかりつつ
- そういう時でも便利機能は提供しつつ
- シンプル構成なものが欲しい
- もともとORMが作るSQLに多くを求めない
- かりかりユーニングしたい場合は自分でSQLを書くし
設計方針
continued...
設計方針
- 生SQLのRができて、inflate,utf8flag周りを処理できればよい
continued...
設計方針
- 生SQLのRができて、inflate,utf8flag周りを処理できればよい
- Rについてはプログラマブルな処理もしたい
continued...
設計方針
- 生SQLのRができて、inflate,utf8flag周りを処理できればよい
- Rについてはプログラマブルな処理もしたい
- DBICのresultsetみたいなインクリメンタルなsearch
continued...
設計方針
- 生SQLのRができて、inflate,utf8flag周りを処理できればよい
- Rについてはプログラマブルな処理もしたい
- DBICのresultsetみたいなインクリメンタルなsearch
- insert,updae,deleteについてはDBICみたいにできればOK
continued...
設計方針
- 生SQLのRができて、inflate,utf8flag周りを処理できればよい
- Rについてはプログラマブルな処理もしたい
- DBICのresultsetみたいなインクリメンタルなsearch
- insert,updae,deleteについてはDBICみたいにできればOK
continued...
設計方針
- 生SQLのRができて、inflate,utf8flag周りを処理できればよい
- Rについてはプログラマブルな処理もしたい
- DBICのresultsetみたいなインクリメンタルなsearch
- insert,updae,deleteについてはDBICみたいにできればOK
- 検索結果をルールベースでオブジェクトにマッピング
continued...
設計方針
- 生SQLのRができて、inflate,utf8flag周りを処理できればよい
- Rについてはプログラマブルな処理もしたい
- DBICのresultsetみたいなインクリメンタルなsearch
- insert,updae,deleteについてはDBICみたいにできればOK
- 検索結果をルールベースでオブジェクトにマッピング
- デバッグしやすいようにオブジェクトに分けまくらない
continued...
設計方針
- 生SQLのRができて、inflate,utf8flag周りを処理できればよい
- Rについてはプログラマブルな処理もしたい
- DBICのresultsetみたいなインクリメンタルなsearch
- insert,updae,deleteについてはDBICみたいにできればOK
- 検索結果をルールベースでオブジェクトにマッピング
- デバッグしやすいようにオブジェクトに分けまくらない
ルールベースって?
continued...
ルールベースって?
- 生のSQLを実行した場合に取得したデータをオブジェクトにする際
continued...
ルールベースって?
- 生のSQLを実行した場合に取得したデータをオブジェクトにする際
- 特定のカラムについてutf8の処理、inflateの処理をする必要がある
continued...
ルールベースって?
- 生のSQLを実行した場合に取得したデータをオブジェクトにする際
- 特定のカラムについてutf8の処理、inflateの処理をする必要がある
- 設定したルールにマッチしたカラム全てに対して処理
continued...
ルールベースって?
- 生のSQLを実行した場合に取得したデータをオブジェクトにする際
- 特定のカラムについてutf8の処理、inflateの処理をする必要がある
- 設定したルールにマッチしたカラム全てに対して処理
- ルールベースとすることによって
continued...
ルールベースって?
- 生のSQLを実行した場合に取得したデータをオブジェクトにする際
- 特定のカラムについてutf8の処理、inflateの処理をする必要がある
- 設定したルールにマッチしたカラム全てに対して処理
- ルールベースとすることによって
- ORM側ではこのカラムがどのテーブルにあるからあーしてこーして
continued...
ルールベースって?
- 生のSQLを実行した場合に取得したデータをオブジェクトにする際
- 特定のカラムについてutf8の処理、inflateの処理をする必要がある
- 設定したルールにマッチしたカラム全てに対して処理
- ルールベースとすることによって
- ORM側ではこのカラムがどのテーブルにあるからあーしてこーして
- を考えない
continued...
ルールベースって?
- 生のSQLを実行した場合に取得したデータをオブジェクトにする際
- 特定のカラムについてutf8の処理、inflateの処理をする必要がある
- 設定したルールにマッチしたカラム全てに対して処理
- ルールベースとすることによって
- ORM側ではこのカラムがどのテーブルにあるからあーしてこーして
- を考えない
- このカラム名の場合はこうだ!
continued...
ルールベースって?
- 生のSQLを実行した場合に取得したデータをオブジェクトにする際
- 特定のカラムについてutf8の処理、inflateの処理をする必要がある
- 設定したルールにマッチしたカラム全てに対して処理
- ルールベースとすることによって
- ORM側ではこのカラムがどのテーブルにあるからあーしてこーして
- を考えない
- このカラム名の場合はこうだ!
- 基本それで十分とおもった
なにはともあれ使い方
continued...
なにはともあれ使い方
package Your::Model;
use DBIx::Skinny setup => +{
dsn => 'dbi:mysql:blog',
username => 'nekokak',
password => 'password',
};
1;
schema設定
continued...
schema設定
package Your::Model::Schema;
use DBIx:Skinny::Schema;
# nop use modules ...
install_table blog => schema {
pk 'id';
columns qw/id guid title body created_at updated_at/;
trigger pre_insert => callback {
my ($class, $args) = @_;
$args->{guid} = Data::GUID->new->as_base64_urlsafe;
$args->{created_at} = DateTime->now(
timezone => $timezone
);
};
};
schema設定続き..
continued...
schema設定続き..
# ....
install_tale tag => schema {
pk 'id';
columns qw/id guid name created_at updated_at/;
};
install_table blog_tag => schema {
pk 'id';
columns qw/id guid blog_id tag_id created_at updated_at/;
};
schema設定続き....
continued...
schema設定続き....
# ...
install_utf8_columns qw/title body name/;
install_inflate_rule '^.+_at$' => callback {
inflate {
my $value = shift;
my $dt = DateTime::Format::Strptime->new(
pattern => '%Y-%m-%d %H:%M:%S',
timezone => $timezone,
);
};
deflate {
my $value = shift;
return DateTime::Format::MySQL->format_datetime($value);
};
};
insert
continued...
insert
use Your::Model;
my $row = Your::Model->insert('blog',
{
title => 'YAPC::Asia 2008',
body => 'こんにちわnekokakです.云々',
}
);
update
continued...
update
$row->update(
{
title => 'YAPC::Asia 2009',
}
)
continued...
update
$row->update(
{
title => 'YAPC::Asia 2009',
}
)
オブジェクトから直接updateもできるし
continued...
update
$row->update(
{
title => 'YAPC::Asia 2009',
}
)
オブジェクトから直接updateもできるし
continued...
update
$row->update(
{
title => 'YAPC::Asia 2009',
}
)
オブジェクトから直接updateもできるし
Your::Model->update('blog',
{
title => 'YAPC::Asia 2009'
},
{ id => $row->id, }
);
continued...
update
$row->update(
{
title => 'YAPC::Asia 2009',
}
)
オブジェクトから直接updateもできるし
Your::Model->update('blog',
{
title => 'YAPC::Asia 2009'
},
{ id => $row->id, }
);
条件指定で一気にupdateもできる
delete
continued...
delete
$row->delete;
continued...
delete
$row->delete;
オブジェクトから直接deleteもできるし
continued...
delete
$row->delete;
オブジェクトから直接deleteもできるし
continued...
delete
$row->delete;
オブジェクトから直接deleteもできるし
Your::Model->delete('blog',{id => $row->id});
continued...
delete
$row->delete;
オブジェクトから直接deleteもできるし
Your::Model->delete('blog',{id => $row->id});
条件を指定してまとめて消す事も出来る
select(search_by_sql)
continued...
select(search_by_sql)
my $itr = Your::Model->search_by_sql(
q{
SELECT title, body FROM blog WHERE id = ?
},
[$row->id]
);
continued...
select(search_by_sql)
my $itr = Your::Model->search_by_sql(
q{
SELECT title, body FROM blog WHERE id = ?
},
[$row->id]
);
continued...
select(search_by_sql)
my $itr = Your::Model->search_by_sql(
q{
SELECT title, body FROM blog WHERE id = ?
},
[$row->id]
);
- 好きにSQLを書いて実行
- scalarコンテキストで受ける場合はイテレータを
continued...
select(search_by_sql)
my $itr = Your::Model->search_by_sql(
q{
SELECT title, body FROM blog WHERE id = ?
},
[$row->id]
);
- 好きにSQLを書いて実行
- scalarコンテキストで受ける場合はイテレータを
- arrayコンテキストで受ける場合は結果の配列を取得
continued...
select(search_by_sql)
my $itr = Your::Model->search_by_sql(
q{
SELECT title, body FROM blog WHERE id = ?
},
[$row->id]
);
- 好きにSQLを書いて実行
- scalarコンテキストで受ける場合はイテレータを
- arrayコンテキストで受ける場合は結果の配列を取得
- while (my $row = $itr->next) { say $row->title }
select(search_named)
continued...
select(search_named)
Your::Model->search_named(q{
SELECT title, body FROM blog WHERE id = :id
},{id => $row->id});
continued...
select(search_named)
Your::Model->search_named(q{
SELECT title, body FROM blog WHERE id = :id
},{id => $row->id});
continued...
select(search_named)
Your::Model->search_named(q{
SELECT title, body FROM blog WHERE id = :id
},{id => $row->id});
- search_by_sqlのちょっと拡張版
- bindさせる値をnamed プレスホルダーにしている
continued...
select(search_named)
Your::Model->search_named(q{
SELECT title, body FROM blog WHERE id = :id
},{id => $row->id});
- search_by_sqlのちょっと拡張版
- bindさせる値をnamed プレスホルダーにしている
- 通常、bindさせる値はarrayrefにして、順番を守る必要がある
continued...
select(search_named)
Your::Model->search_named(q{
SELECT title, body FROM blog WHERE id = :id
},{id => $row->id});
- search_by_sqlのちょっと拡張版
- bindさせる値をnamed プレスホルダーにしている
- 通常、bindさせる値はarrayrefにして、順番を守る必要がある
- 順番ずれただけで変になる
continued...
select(search_named)
Your::Model->search_named(q{
SELECT title, body FROM blog WHERE id = :id
},{id => $row->id});
- search_by_sqlのちょっと拡張版
- bindさせる値をnamed プレスホルダーにしている
- 通常、bindさせる値はarrayrefにして、順番を守る必要がある
- 順番ずれただけで変になる
- ?じゃなくて:idのように名前をつける事でbindミスを無くせる
select(search/single/count)
continued...
select(search/single/count)
Your::Model->search('blog',{id => $row->id});
continued...
select(search/single/count)
Your::Model->search('blog',{id => $row->id});
Your::Model->single('blog',{id => $row->id});
continued...
select(search/single/count)
Your::Model->search('blog',{id => $row->id});
Your::Model->single('blog',{id => $row->id});
Your::Model->count('blog', 'id', {});
continued...
select(search/single/count)
Your::Model->search('blog',{id => $row->id});
Your::Model->single('blog',{id => $row->id});
Your::Model->count('blog', 'id', {});
resultset
continued...
select(search/single/count)
Your::Model->search('blog',{id => $row->id});
Your::Model->single('blog',{id => $row->id});
Your::Model->count('blog', 'id', {});
resultset
- ちょと複雑なんだけど、CGIなんかでユーザが入力した条件をもとにクエリを組み立てたい場合
continued...
select(search/single/count)
Your::Model->search('blog',{id => $row->id});
Your::Model->single('blog',{id => $row->id});
Your::Model->count('blog', 'id', {});
resultset
- ちょと複雑なんだけど、CGIなんかでユーザが入力した条件をもとにクエリを組み立てたい場合
my $rs = Your:Model->resultset;
$rs->add_select('blog.id' => 'blog_id');
$rs->from(['blog']);
$rs->add_where('blog.title' => 'YAPC::Asia 2009');
my $itr = $rs->retrieve;
continued...
select(search/single/count)
Your::Model->search('blog',{id => $row->id});
Your::Model->single('blog',{id => $row->id});
Your::Model->count('blog', 'id', {});
resultset
- ちょと複雑なんだけど、CGIなんかでユーザが入力した条件をもとにクエリを組み立てたい場合
my $rs = Your:Model->resultset;
$rs->add_select('blog.id' => 'blog_id');
$rs->from(['blog']);
$rs->add_where('blog.title' => 'YAPC::Asia 2009');
my $itr = $rs->retrieve;
find_or_create
continued...
find_or_create
continued...
find_or_create
Your::Model->find_or_create('user',
{
name => 'nekokak',
email => 'nekokak@gmail.cim',
}
);
bulk_insert
continued...
find_or_create
Your::Model->find_or_create('user',
{
name => 'nekokak',
email => 'nekokak@gmail.cim',
}
);
bulk_insert
Your::Model->bulk_insert('user',[{
name => 'nekokak',
email => 'nekokak@gmail.com',
},
{
name => 'yappo',
email => 'yappo@example.com',
},]);
トランザクションサポート
continued...
トランザクションサポート
my $txn = Your::Model->txn_scope;
my $row = Your::Model->single('blog', {id => 1});
$row->set({title => 'やっぷしー2009'});
$row->update;
$txn->commit;
クラスベースorインスタンスベース
continued...
クラスベースorインスタンスベース
- SkinnyはYour::Model->searchのようにクラスから直接メソッド呼び出し可能
continued...
クラスベースorインスタンスベース
- SkinnyはYour::Model->searchのようにクラスから直接メソッド呼び出し可能
- my $model = Your::Model->new; $model->searchのようにインスタンスを生成してからメソッドを呼び出す事も可能
continued...
クラスベースorインスタンスベース
- SkinnyはYour::Model->searchのようにクラスから直接メソッド呼び出し可能
- my $model = Your::Model->new; $model->searchのようにインスタンスを生成してからメソッドを呼び出す事も可能
- newメソッドを呼び出す時にconnection情報を設定すれば、コネクションを分けたインスタンスを生成する事が可能
continued...
クラスベースorインスタンスベース
- SkinnyはYour::Model->searchのようにクラスから直接メソッド呼び出し可能
- my $model = Your::Model->new; $model->searchのようにインスタンスを生成してからメソッドを呼び出す事も可能
- newメソッドを呼び出す時にconnection情報を設定すれば、コネクションを分けたインスタンスを生成する事が可能
- 処理毎にコネクションを管理したいとかの場合にインスタンスを生成し使用
continued...
クラスベースorインスタンスベース
- SkinnyはYour::Model->searchのようにクラスから直接メソッド呼び出し可能
- my $model = Your::Model->new; $model->searchのようにインスタンスを生成してからメソッドを呼び出す事も可能
- newメソッドを呼び出す時にconnection情報を設定すれば、コネクションを分けたインスタンスを生成する事が可能
- 処理毎にコネクションを管理したいとかの場合にインスタンスを生成し使用
- インスタンスを作ってコネクションを管理するまでもない場合はクラスから直接
continued...
クラスベースorインスタンスベース
- SkinnyはYour::Model->searchのようにクラスから直接メソッド呼び出し可能
- my $model = Your::Model->new; $model->searchのようにインスタンスを生成してからメソッドを呼び出す事も可能
- newメソッドを呼び出す時にconnection情報を設定すれば、コネクションを分けたインスタンスを生成する事が可能
- 処理毎にコネクションを管理したいとかの場合にインスタンスを生成し使用
- インスタンスを作ってコネクションを管理するまでもない場合はクラスから直接
- 細かい使い方についてはDBIx::Skinny::Manual::*に日本語ドキュメントがあるのでみてちょ
relationship
continued...
relationship
- テーブル間のリレーションをSkinnyではどのように対応させるか
continued...
relationship
- テーブル間のリレーションをSkinnyではどのように対応させるか
- 答え
continued...
relationship
- テーブル間のリレーションをSkinnyではどのように対応させるか
- 答え
- 特に何もしない
continued...
relationship
- テーブル間のリレーションをSkinnyではどのように対応させるか
- 答え
- 特に何もしない
- DBICのようなhas_many/belongs_toなどはない
continued...
relationship
- テーブル間のリレーションをSkinnyではどのように対応させるか
- 答え
- 特に何もしない
- DBICのようなhas_many/belongs_toなどはない
- ORMなのに?
continued...
relationship
- テーブル間のリレーションをSkinnyではどのように対応させるか
- 答え
- 特に何もしない
- DBICのようなhas_many/belongs_toなどはない
- ORMなのに?
- あると便利だからあると使う
continued...
relationship
- テーブル間のリレーションをSkinnyではどのように対応させるか
- 答え
- 特に何もしない
- DBICのようなhas_many/belongs_toなどはない
- ORMなのに?
- あると便利だからあると使う
continued...
relationship
- テーブル間のリレーションをSkinnyではどのように対応させるか
- 答え
- 特に何もしない
- DBICのようなhas_many/belongs_toなどはない
- ORMなのに?
- あると便利だからあると使う
- これが問題な時がある
- そこにクエリが発行されている事を意識しているのか?
continued...
relationship
- テーブル間のリレーションをSkinnyではどのように対応させるか
- 答え
- 特に何もしない
- DBICのようなhas_many/belongs_toなどはない
- ORMなのに?
- あると便利だからあると使う
- これが問題な時がある
- そこにクエリが発行されている事を意識しているのか?
- 使い方によってはリレーションをたどるために数百回のクエリが発行される可能性がある
continued...
relationship
- テーブル間のリレーションをSkinnyではどのように対応させるか
- 答え
- 特に何もしない
- DBICのようなhas_many/belongs_toなどはない
- ORMなのに?
- あると便利だからあると使う
- これが問題な時がある
- そこにクエリが発行されている事を意識しているのか?
- 使い方によってはリレーションをたどるために数百回のクエリが発行される可能性がある
- リレーションサポートするのであれば今までとちがう設計方法をもとにやりたい
continued...
relationship
- テーブル間のリレーションをSkinnyではどのように対応させるか
- 答え
- 特に何もしない
- DBICのようなhas_many/belongs_toなどはない
- ORMなのに?
- あると便利だからあると使う
- これが問題な時がある
- そこにクエリが発行されている事を意識しているのか?
- 使い方によってはリレーションをたどるために数百回のクエリが発行される可能性がある
- リレーションサポートするのであれば今までとちがう設計方法をもとにやりたい
- Skinnyで無理にサポートするつもりはいまのところない
ラッパー
continued...
ラッパー
- Skinnyはなるべく小さく設計している
- Coreにいれるほどでもないなーとかいう使い勝手部分の拡張はラッパーを書く事をおすすめ
continued...
ラッパー
- Skinnyはなるべく小さく設計している
- Coreにいれるほどでもないなーとかいう使い勝手部分の拡張はラッパーを書く事をおすすめ
- 例えばnekoyaさんがDBIx::Skinny::ARというのをかいてます
continued...
ラッパー
- Skinnyはなるべく小さく設計している
- Coreにいれるほどでもないなーとかいう使い勝手部分の拡張はラッパーを書く事をおすすめ
- 例えばnekoyaさんがDBIx::Skinny::ARというのをかいてます
- もちろんCoreで対応すべき部分は対応していくので色々ご意見募集中
continued...
ラッパー
- Skinnyはなるべく小さく設計している
- Coreにいれるほどでもないなーとかいう使い勝手部分の拡張はラッパーを書く事をおすすめ
- 例えばnekoyaさんがDBIx::Skinny::ARというのをかいてます
- もちろんCoreで対応すべき部分は対応していくので色々ご意見募集中
- あと、おいぬめさんがSkinnyを参考にDBIx::Thinというのを開発中
continued...
ラッパー
- Skinnyはなるべく小さく設計している
- Coreにいれるほどでもないなーとかいう使い勝手部分の拡張はラッパーを書く事をおすすめ
- 例えばnekoyaさんがDBIx::Skinny::ARというのをかいてます
- もちろんCoreで対応すべき部分は対応していくので色々ご意見募集中
- あと、おいぬめさんがSkinnyを参考にDBIx::Thinというのを開発中
- やっぱりSkinnyみたいな方向性はありなんだなと再認識できた
Skinnyの満足している部分
continued...
Skinnyの満足している部分
continued...
Skinnyの満足している部分
- 生SQLが扱いやすくなった
- Skinnyが作るオブジェクトは小さいのでアプリ側でデバッグしやすくなった
continued...
Skinnyの満足している部分
- 生SQLが扱いやすくなった
- Skinnyが作るオブジェクトは小さいのでアプリ側でデバッグしやすくなった
- DBICより早い!
continued...
Skinnyの満足している部分
- 生SQLが扱いやすくなった
- Skinnyが作るオブジェクトは小さいのでアプリ側でデバッグしやすくなった
- DBICより早い!
continued...
Skinnyの満足している部分
- 生SQLが扱いやすくなった
- Skinnyが作るオブジェクトは小さいのでアプリ側でデバッグしやすくなった
- DBICより早い!
- 機能が少ないので早いのは当然だ:(
- なのであえてベンチマークは特別とらない
Skinnyの足りない部分
continued...
Skinnyの足りない部分
continued...
Skinnyの足りない部分
continued...
Skinnyの足りない部分
- 対応しているDBD
- 現在の所SQLiteとMySQLのみ
- 手伝ってくれる勇者募集中
continued...
Skinnyの足りない部分
- 対応しているDBD
- 現在の所SQLiteとMySQLのみ
- 手伝ってくれる勇者募集中
- ドキュメント
continued...
Skinnyの足りない部分
- 対応しているDBD
- 現在の所SQLiteとMySQLのみ
- 手伝ってくれる勇者募集中
- ドキュメント
- 細かい使い方など日本語ドキュメントしか用意していない
continued...
Skinnyの足りない部分
- 対応しているDBD
- 現在の所SQLiteとMySQLのみ
- 手伝ってくれる勇者募集中
- ドキュメント
- 細かい使い方など日本語ドキュメントしか用意していない
- ユーザさんへ
continued...
Skinnyの足りない部分
- 対応しているDBD
- 現在の所SQLiteとMySQLのみ
- 手伝ってくれる勇者募集中
- ドキュメント
- 細かい使い方など日本語ドキュメントしか用意していない
- ユーザさんへ
continued...
Skinnyの足りない部分
- 対応しているDBD
- 現在の所SQLiteとMySQLのみ
- 手伝ってくれる勇者募集中
- ドキュメント
- 細かい使い方など日本語ドキュメントしか用意していない
- ユーザさんへ
- 数人につかってもらっているみたい
- でも、作ってる本人があまり使い方など細かい事をFeedbackしてないの
continued...
Skinnyの足りない部分
- 対応しているDBD
- 現在の所SQLiteとMySQLのみ
- 手伝ってくれる勇者募集中
- ドキュメント
- 細かい使い方など日本語ドキュメントしか用意していない
- ユーザさんへ
- 数人につかってもらっているみたい
- でも、作ってる本人があまり使い方など細かい事をFeedbackしてないの
- CPANにもあぷったのでぼちぼちかいてく
DBIx::Skinnyまとめ
continued...
DBIx::Skinnyまとめ
- とりあえずやりたい事は大体できるようにはなってきた
continued...
DBIx::Skinnyまとめ
- とりあえずやりたい事は大体できるようにはなってきた
- 興味のある人は公開してるので触ってみてください
continued...
DBIx::Skinnyまとめ
- とりあえずやりたい事は大体できるようにはなってきた
- 興味のある人は公開してるので触ってみてください
- repos.
continued...
DBIx::Skinnyまとめ
continued...
DBIx::Skinnyまとめ
continued...