コンディションに関する詳細 | Database

コンディションは少々複雑かもしれません。それは様々な生成方法、また設定方法があるからです。ファインダのみを使用するなどルールを決定できれば良いかもしれませんが、モデルが既に生成されている場合などは、setCondition() で条件を与えて取得する必要があるからです。

まず、モデルの setCondition() メソッドには次の4種類の値が渡せることを理解してください。
  • setCondition(string column, mixed value) - column が value 等しい
  • setCondition(mixed value) - primary key が value と等しい
  • setCondition(mixed condition) - コンディションオブジェクト(後で説明)
  • setCondition(Sabel_Db_Model model) - 後で説明
1つ目と2つ目はこちらで使用している通りです。また、3つ目に関しても、当ページのサンプルコード各所で使用しています。コンディションオブジェクトとは、1つは Sabel_Db_Condition::create() で生成されるものです。
// "age" が30以上を示すコンディションオブジェクト
$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::GREATER_EQUAL, "age", 30
);
"column = value"のような単純なものは今まで setCondition(column, value) を使用してきましたが、これも Sabel_Db_Condition::create() を使用してコンディションオブジェクトを作り出すことができます。
// "status" が1を示すコンディションオブジェクト
$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::EQUAL, "status", 1
);
つまり、下記の2つのコードは全く同様の働きをします。簡単に言えば、setCondition() は EQUALコンディション の場合のみ、わざわざ Sabel_Db_Condition::create() で生成したコンディションオブジェクトを渡さなくても良いということになります。
$model->setCondition("status", 1);
----------------------------------------------------
$model->setCondition(Sabel_Db_Condition::create(
  Sabel_Db_Condition::EQUAL, "status", 1
));
また、2つの特殊なコンディションオブジェクトがあり、それは Sabel_Db_Condition_Or と Sabel_Db_Condition_And です。これらのオブジェクトにはコンディションオブジェクト、また、これら自身を追加していくことができます。
$or1 = new Sabel_Db_Condition_Or();
$or1->add(Sabel_Db_Condition::create(Sabel_Db_Condition::EQUAL, "a", 1));
$or1->add(Sabel_Db_Condition::create(Sabel_Db_Condition::EQUAL, "b", 2));

$or2 = new Sabel_Db_Condition_Or();
$or2->add(Sabel_Db_Condition::create(Sabel_Db_Condition::EQUAL, "c", 3));
$or2->add(Sabel_Db_Condition::create(Sabel_Db_Condition::EQUAL, "d", 4));

$and = new Sabel_Db_Condition_And();
$and->add(Sabel_Db_Condition::create(Sabel_Db_Condition::EQUAL, "e", 5));
$and->add(Sabel_Db_Condition::create(Sabel_Db_Condition::EQUAL, "f", 6));

$or = new Sabel_Db_Condition_Or();
$or->add($or1)->add($or2)->add($and);

$condition = new Sabel_Db_Condition_And();
$condition->add($or);
$condition->add(Sabel_Db_Condition::create(Sabel_Db_Condition::EQUAL, "g", 7));

$model->setCondition($condition);

=> ((a = 1 OR b = 2) OR (c = 3 OR d = 4) OR (e = 5 AND f = 6)) AND g = 7
参照関係にあるモデルは、それ自体をコンディションとして使用することもできます(ページ上部の4つ目)。例えばあるユーザが投稿した記事を、下記のように取得することができます。
$arArticle = new Article();
$articles = $arArticle->select($aUser);
----------------------------------------------------
$arArticle = new Article();
$arArticle->setCondition($aUser);
$articles = $arArticle->select();
これはデータベースから参照関係(外部キー制約)の情報を取得することによって実現しています。また、外部キー制約を定義していない場合やSQLiteなど外部キー制約自体無いデータベースでも、規約に則っている場合はこの仕組みを使用することができます。規約とは、上記の例で言えば記事テーブルの "user_id" カラムがユーザテーブルの "id" カラムを参照しているということです。
規約に関する詳細はこちらを参照してください。

Sabel 1.2からはファインダが実装され、それとともにコンディションオブジェクトを簡単に生成する関数が用意されました。例えばEQUALコンディションは下記のように、eq()関数 で生成できます。
$condition = eq("status", 1);
関数が返すものもコンディションオブジェクトに変わりはないので、モデルの setCondition() に渡すことが可能です。
$model->setCondition(eq("status", 1));
ファインダには同名の eq()メソッド がありますが、生成したコンディションオブジェクトを where()メソッド に渡すことができます。なお、where()メソッド には省略系の w()メソッド があります。
$finder->eq("status", 1);
----------------------------------------------------
$finder->w(eq("status", 1));
----------------------------------------------------
※もちろんこれもOK
$finder->w(Sabel_Db_Condition::create(
  Sabel_Db_Condition::EQUAL, "status", 1
));
ORやANDを生成する ow() や aw() 関数もあります。これらの関数は可変長の引数(コンディションオブジェクト)を受け取ります。
$condition = ow(eq("a", 1), eq("b", 2));  // a = 1 OR b = 2
$condition = aw(ow(eq("a", 1), eq("b", 2)), eq("c", 3));  // (a = 1 OR b = 2) AND c = 3
Sabel_Db_Condition::create() で生成する場合と関数で生成する場合の例を下記に示します。

EQUAL(等しい)

a = 1

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::EQUAL, "a", 1
);
----------------------------------------------------
$condition = eq("a", 1);

NOT EQUAL(等しくない)

a != 1 ( NOT a = 1 , a <> 1)

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::EQUAL, "a", 1, true
);
----------------------------------------------------
$condition = neq("a", 1);

IN (いずれかである)

a IN (x, y, z...)

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::IN, "a", array(x, y, z...)
);
----------------------------------------------------
$condition = in("a", array(x, y, z...));

NOT IN (いずれでもない)

NOT a IN (x, y, z...)

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::IN, "a", array(x, y, z...), true
);
----------------------------------------------------
$condition = nin("a", array(x, y, z...));

LESS THAN (より小さい)

a < 1

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::LESS_THAN, "a", 1
);
----------------------------------------------------
$condition = lt("a", 1);

LESS EQUAL (以下である)

a <= 1

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::LESS_EQUAL, "a", 1
);
----------------------------------------------------
$condition = le("a", 1);

GREATER THAN (より大きい)

a > 1

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::GREATER_THAN, "a", 1
);
----------------------------------------------------
$condition = gt("a", 1);

GREATER EQUAL (以上である)

a >= 1

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::GREATER_EQUAL, "a", 1
);
----------------------------------------------------
$condition = ge("a", 1);

BETWEEN (xとyの間である(x, y自身を含む))

a BETWEEN x AND y

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::BETWEEN, "a", array(x, y)
);
----------------------------------------------------
$condition = bw("a", array(x, y)); ( OR bw("a", x, y); )

NOT BETWEEN (xとyの間ではない(x, y自身も含まない))

NOT a BETWEEN x AND y

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::BETWEEN, "a", array(x, y), true
);
----------------------------------------------------
$condition = nbw("a", array(x, y)); ( OR nbw("a", x, y); )

LIKE (strで始まる)

a LIKE 'str%'

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::LIKE, "a", "str"
)->type(Sabel_Db_Condition_Like::STARTS_WITH);
----------------------------------------------------
$condition = starts("a", str);

LIKE (strを含む)

a LIKE '%str%'

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::LIKE, "a", "str"
)->type(Sabel_Db_Condition_Like::CONTAINS);
----------------------------------------------------
$condition = contains("a", str);

LIKE (strで終わる)

a LIKE '%str'

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::LIKE, "a", "str"
)->type(Sabel_Db_Condition_Like::ENDS_WITH);
----------------------------------------------------
$condition = ends("a", str);

IS NULL (NULLである)

a IS NULL

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::ISNULL, "a"
);
----------------------------------------------------
$condition = isNull("a", str);

IS NOT NULL (NULLでない)

a IS NOT NULL

$condition = Sabel_Db_Condition::create(
  Sabel_Db_Condition::ISNOTNULL, "a"
);
----------------------------------------------------
$condition = isNotNull("a", str);