Perl Hackers Hub

第3回 DBIx::Classでデータベース操作(1)

この記事を読むのに必要な時間:およそ 4 分

本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回はカヤックの村瀬大輔さんで,テーマはDBIx::Classです。

DBIx::Classとは

DBIx::ClassはPerlのO/Rマッピングモジュールです。O/RマッピングObject/Relational Mapping以下ORM)とは,オブジェクト指向言語におけるオブジェクトとリレーショナルデータベースを紐づけるしくみのことで,ORMを使用するとユーザは直感的なオブジェクト操作によってデータベースを操作できるようになります。

DBIx::ClassはPerlのORMとしては現在世界で一番使われているモジュールです。日本では最近データベース操作モジュールとしてより軽量なDBIx::SkinnyやData::Modelなどの注目が高まってきていますが,機能的に枯れている点や豊富にテストされている点でDBIx::Classが現時点では最も信頼できるデータベース操作モジュールと言えるでしょう。

DBIx::Classも登場時にはいろいろな記事になりましたが,最近ではあまり取り上げられることもなくなりました。しかし登場時と比べると機能はずいぶん強化され,基本的な使い方での推奨方法も若干変更されていたりします。本稿では基本的な使い方を一通りおさらいしたあと,日本ではあまり記事にされていない発展的な使い方をいくつか紹介します。

サンプルDBスキーマ

本稿ではリスト1の定義のデータベースをサンプルとして使用します。このサンプルデータベースはTwitterのデータ構造を模したものになっていて,次のテーブルを持ちます。

  • user:ユーザ
  • tweet:つぶやき
  • following_map:フォロー関係
  • user_profile:ユーザ詳細プロフィール

リスト1 サンプルDBスキーマ

CREATE TABLE user (
    id INTEGER NOT NULL PRIMARY KEY,
    username VARCHAR(255) NOT NULL
);

CREATE TABLE user_profile (
    id INTEGER NOT NULL PRIMARY KEY, -- user.id
    full_name VARCHAR(255) NOT NULL,
    bio VARCHAR(255)
);

CREATE TABLE following_map (
    id INTEGER NOT NULL PRIMARY KEY,
    user INTEGER NOT NULL, -- user.id
    target INTEGER NOT NULL -- user.id
);

CREATE TABLE tweet (
    id INTEGER NOT NULL PRIMARY KEY,
    user INTEGER NOT NULL, -- user.id
    body VARCHAR(255) NOT NULL,
    created_date DATETIME NOT NULL,
    modified_date DATETIME NOT NULL
);

基本的な使い方

まずはDBIx::Classの基本的な使い方を見てみましょう。

データベースクラス定義

DBIx::Classを使うには,まずそれを継承した自前のクラスを作成し,使用するデータベース情報を定義します。作成するクラスは次の3つがあります。

  • Schemaクラス
  • Resultクラス
  • ResultSetクラス
●Schemaクラス

SchemaクラスはDBIx::Classを使ううえでベースとなるクラスで,次のように定義します。

package My::Schema;
use strict;
use warnings;
use base 'DBIx::Class::Schema';

__PACKAGE__->load_namespaces;
1;

この例ではMy::Schemaというクラス名でSchemaクラスを作成しています。

SchemaクラスはDBIx::Class::Schemaを継承して作成し,その中ではどのようにコンポーネントクラスを読み込むかなどを定義します。後方互換的にいろいろな定義方法があるのですが,現在は例のようにload_namespacesを使用するのが一般的です。

load_namespacesは,

  • My::Schema::Result::*にあるResultクラス
  • My::Schema::ResultSet::*にあるResultSetクラス

を自動的にロードするメソッドです。

●Resultクラス

Resultクラスはデータベースのテーブルを表すクラスで,操作する必要のあるテーブルの数だけ定義する必要があります。

Resultクラスは次のようにDBIx::Class::Coreを継承して作成します。

package My::Schema::Result::User;
use strict;
use warnings;
use base 'DBIx::Class::Core';

そしてこのResultクラスがデータベースのどのテーブルに紐付いているかを定義します。

__PACKAGE__->table('user');

続いてそのテーブルがどのようなカラムを持つのかも定義します。

__PACKAGE__->add_columns(qw/id username/);

カラム名だけでなく,より詳細な情報を登録することもできます。

__PACKAGE__->add_columns(
    id => {
        data_type         => 'INTEGER',
        is_nullable       => 0,
        is_auto_increment => 1,
    },
    username => {
        data_type   => 'VARCHAR',
        size        => 255,
        is_nullable => 0,
    },
);

DBIx::Classのコアではこの詳細情報は使われないので必ずしも詳細に定義する必要はありませんが,詳細に定義しておくとこの情報からデータベースにCREATETABLEを発行したり,DBIx::Class::WebFormなどのコンポーネントが使用できるようになったりします。

そして,プライマリキーの設定をします。

__PACKAGE__->set_primary_key('id');

ここまでが,テーブル定義に最低限必要な記述です。

●ResultSetクラス

ResultSetクラスはResultクラスの集合を表すクラスです。このクラスの定義は必須ではありません。定義しなかった場合はデフォルトのDBIx::Class::ResultSetがそのまま使用されます。

著者プロフィール

村瀬大輔(むらせだいすけ,ハンドルネーム:typester)

1981年2月生まれ。2004年9月株式会社カヤックに入社。

カヤックでは自社サービス「こえ部」を担当する傍ら,ラボチームBM11に所属し「Ark」「nim」といったオープンソースプロダクトを開発。また「Shibuya.pm」や「YAPC::Asia」にスピーカーとして参加するなど,Perlプログラマとして活躍の場を広げている。

コメント

コメントの記入